account-polld-0.1+16.04.20160308.1/0000755000015600001650000000000012667557117016642 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/qtcontact/0000755000015600001650000000000012667557117020642 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/qtcontact/qtcontacts.h0000644000015600001650000000145012667556700023173 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __QTCONTACTS_GOLANG__ #define __QTCONTACTS_GOLANG__ #ifdef __cplusplus extern "C" { #endif char* getAvatar(char *); int mainloopStart(); #ifdef __cplusplus } #endif #endif account-polld-0.1+16.04.20160308.1/qtcontact/contacts.go0000644000015600001650000000264112667556700023007 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package qtcontact // #cgo CXXFLAGS: -std=c++0x -pedantic-errors -Wall -fno-strict-aliasing -I/usr/share/c++/4.8 // #cgo LDFLAGS: -lstdc++ // #cgo pkg-config: Qt5Core Qt5Contacts // #include "qtcontacts.h" import "C" import ( "log" "time" ) func MainLoopStart() { go C.mainloopStart() } // GetAvatar retrieves an avatar path for the specified email // address. Multiple calls to this func will be in sync func GetAvatar(emailAddress string) string { if emailAddress == "" { return "" } avatarPathChan := make(chan string, 1) go func() { avatarPathChan <- C.GoString(C.getAvatar(C.CString(emailAddress))) }() for { select { case path := <-avatarPathChan: return path case <-time.After(8 * time.Second): log.Println("Timeout while seeking avatar for", emailAddress) return "" } } } account-polld-0.1+16.04.20160308.1/qtcontact/qtcontacts.moc0000644000015600001650000000470712667556700023532 0ustar pbuserpbgroup00000000000000/**************************************************************************** ** Meta object code from reading C++ file 'qtcontacts.hpp' ** ** Created by: The Qt Meta Object Compiler version 67 (Qt 5.2.1) ** ** WARNING! All changes made in this file will be lost! *****************************************************************************/ #include "qtcontacts.hpp" #include #include #if !defined(Q_MOC_OUTPUT_REVISION) #error "The header file 'qtcontacts.hpp' doesn't include ." #elif Q_MOC_OUTPUT_REVISION != 67 #error "This file was generated using the moc from 5.2.1. It" #error "cannot be used with the include files from this version of Qt." #error "(The moc has changed too much.)" #endif QT_BEGIN_MOC_NAMESPACE struct qt_meta_stringdata_Avatar_t { QByteArrayData data[1]; char stringdata[8]; }; #define QT_MOC_LITERAL(idx, ofs, len) \ Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \ offsetof(qt_meta_stringdata_Avatar_t, stringdata) + ofs \ - idx * sizeof(QByteArrayData) \ ) static const qt_meta_stringdata_Avatar_t qt_meta_stringdata_Avatar = { { QT_MOC_LITERAL(0, 0, 6) }, "Avatar\0" }; #undef QT_MOC_LITERAL static const uint qt_meta_data_Avatar[] = { // content: 7, // revision 0, // classname 0, 0, // classinfo 0, 0, // methods 0, 0, // properties 0, 0, // enums/sets 0, 0, // constructors 0, // flags 0, // signalCount 0 // eod }; void Avatar::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a) { Q_UNUSED(_o); Q_UNUSED(_id); Q_UNUSED(_c); Q_UNUSED(_a); } const QMetaObject Avatar::staticMetaObject = { { &QObject::staticMetaObject, qt_meta_stringdata_Avatar.data, qt_meta_data_Avatar, qt_static_metacall, 0, 0} }; const QMetaObject *Avatar::metaObject() const { return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject; } void *Avatar::qt_metacast(const char *_clname) { if (!_clname) return 0; if (!strcmp(_clname, qt_meta_stringdata_Avatar.stringdata)) return static_cast(const_cast< Avatar*>(this)); return QObject::qt_metacast(_clname); } int Avatar::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; return _id; } QT_END_MOC_NAMESPACE account-polld-0.1+16.04.20160308.1/qtcontact/qtcontacts.hpp0000644000015600001650000000163512667556700023540 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef __QTCONTACTS_HPP_ #define __QTCONTACTS_HPP_ #include #include class Avatar : QObject { Q_OBJECT public: explicit Avatar(QObject* parent=0) : QObject(parent) { } QString retrieveThumbnail(const QString& email); }; #endif account-polld-0.1+16.04.20160308.1/qtcontact/qtcontacts.cpp0000644000015600001650000000354312667556700023533 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include #include #include #include #include #include #include "qtcontacts.h" #include "qtcontacts.hpp" #include "qtcontacts.moc" #ifdef __cplusplus extern "C" { #include "_cgo_export.h" } #endif QTCONTACTS_USE_NAMESPACE int mainloopStart() { static char empty[1] = {0}; static char *argv[] = {empty, empty, empty}; static int argc = 1; QCoreApplication mApp(argc, argv); return mApp.exec(); } char* getAvatar(char *email) { QScopedPointer avatar(new Avatar()); QString thumbnailPath = avatar->retrieveThumbnail(QString(email)); QByteArray byteArray = thumbnailPath.toUtf8(); char* cString = byteArray.data(); return cString; } QString Avatar::retrieveThumbnail(const QString& email) { QString avatar; QContactManager manager ("galera"); QContactDetailFilter filter(QContactEmailAddress::match(email)); QList contacts = manager.contacts(filter); if(contacts.size() > 0) { avatar = contacts[0].detail().imageUrl().path(); } return avatar; } account-polld-0.1+16.04.20160308.1/plugins/0000755000015600001650000000000012667557117020323 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/plugins/gmail/0000755000015600001650000000000012667557117021414 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/plugins/gmail/gmail.go0000644000015600001650000002437412667556715023051 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package gmail import ( "encoding/json" "fmt" "net/http" "net/mail" "net/url" "os" "regexp" "sort" "strings" "time" "log" "launchpad.net/account-polld/accounts" "launchpad.net/account-polld/gettext" "launchpad.net/account-polld/plugins" "launchpad.net/account-polld/qtcontact" ) const ( APP_ID = "com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail" gmailDispatchUrl = "https://mail.google.com/mail/mu/mp/#cv/priority/^smartlabel_%s/%s" // If there's more than 10 emails in one batch, we don't show 10 notification // bubbles, but instead show one summary. We always show all notifications in the // indicator. individualNotificationsLimit = 10 pluginName = "gmail" ) type reportedIdMap map[string]time.Time var baseUrl, _ = url.Parse("https://www.googleapis.com/gmail/v1/users/me/") // timeDelta defines how old messages can be to be reported. var timeDelta = time.Duration(time.Hour * 24) // trackDelta defines how old messages can be before removed from tracking var trackDelta = time.Duration(time.Hour * 24 * 7) // relativeTimeDelta is the same as timeDelta var relativeTimeDelta string = "1d" // regexp for identifying non-ascii characters var nonAsciiChars, _ = regexp.Compile("[^\x00-\x7F]") type GmailPlugin struct { // reportedIds holds the messages that have already been notified. This // approach is taken against timestamps as it avoids needing to call // get on the message. reportedIds reportedIdMap accountId uint } func idsFromPersist(accountId uint) (ids reportedIdMap, err error) { err = plugins.FromPersist(pluginName, accountId, &ids) if err != nil { return nil, err } // discard old ids timestamp := time.Now() for k, v := range ids { delta := timestamp.Sub(v) if delta > trackDelta { log.Print("gmail plugin ", accountId, ": deleting ", k, " as ", delta, " is greater than ", trackDelta) delete(ids, k) } } return ids, nil } func (ids reportedIdMap) persist(accountId uint) (err error) { err = plugins.Persist(pluginName, accountId, ids) if err != nil { log.Print("gmail plugin ", accountId, ": failed to save state: ", err) } return nil } func New(accountId uint) *GmailPlugin { reportedIds, err := idsFromPersist(accountId) if err != nil { log.Print("gmail plugin ", accountId, ": cannot load previous state from storage: ", err) } else { log.Print("gmail plugin ", accountId, ": last state loaded from storage") } return &GmailPlugin{reportedIds: reportedIds, accountId: accountId} } func (p *GmailPlugin) ApplicationId() plugins.ApplicationId { return plugins.ApplicationId(APP_ID) } func (p *GmailPlugin) Poll(authData *accounts.AuthData) ([]*plugins.PushMessageBatch, error) { // This envvar check is to ease testing. if token := os.Getenv("ACCOUNT_POLLD_TOKEN_GMAIL"); token != "" { authData.AccessToken = token } resp, err := p.requestMessageList(authData.AccessToken) if err != nil { return nil, err } messages, err := p.parseMessageListResponse(resp) if err != nil { return nil, err } // TODO use the batching API defined in https://developers.google.com/gmail/api/guides/batch for i := range messages { resp, err := p.requestMessage(messages[i].Id, authData.AccessToken) if err != nil { return nil, err } messages[i], err = p.parseMessageResponse(resp) if err != nil { return nil, err } } notif, err := p.createNotifications(messages) if err != nil { return nil, err } return []*plugins.PushMessageBatch{ &plugins.PushMessageBatch{ Messages: notif, Limit: individualNotificationsLimit, OverflowHandler: p.handleOverflow, Tag: "gmail", }}, nil } func (p *GmailPlugin) reported(id string) bool { _, ok := p.reportedIds[id] return ok } func (p *GmailPlugin) createNotifications(messages []message) ([]*plugins.PushMessage, error) { timestamp := time.Now() pushMsgMap := make(pushes) for _, msg := range messages { hdr := msg.Payload.mapHeaders() from := hdr[hdrFROM] var avatarPath string emailAddress, err := mail.ParseAddress(from) if err != nil { // If the email address contains non-ascii characters, we get an // error so we're going to try again, this time mangling the name // by removing all non-ascii characters. We only care about the email // address here anyway. // XXX: We can't check the error message due to [1]: the error // message is different in go < 1.3 and > 1.5. // [1] https://github.com/golang/go/issues/12492 mangledAddr := nonAsciiChars.ReplaceAllString(from, "") mangledEmail, mangledParseError := mail.ParseAddress(mangledAddr) if mangledParseError == nil { emailAddress = mangledEmail } } else if emailAddress.Name != "" { // We only want the Name if the first ParseAddress // call was successful. I.e. we do not want the name // from a mangled email address. from = emailAddress.Name } if emailAddress != nil { avatarPath = qtcontact.GetAvatar(emailAddress.Address) // If icon path starts with a path separator, assume local file path, // encode it and prepend file scheme defined in RFC 1738. if strings.HasPrefix(avatarPath, string(os.PathSeparator)) { avatarPath = url.QueryEscape(avatarPath) avatarPath = "file://" + avatarPath } } msgStamp := hdr.getTimestamp() if _, ok := pushMsgMap[msg.ThreadId]; ok { // TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread pushMsgMap[msg.ThreadId].Notification.Card.Summary += fmt.Sprintf(gettext.Gettext(", %s"), from) } else if timestamp.Sub(msgStamp) < timeDelta { // TRANSLATORS: the %s is the "from" header corresponding to a specific email summary := fmt.Sprintf(gettext.Gettext("%s"), from) // TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" body := fmt.Sprintf(gettext.Gettext("%s\n%s"), hdr[hdrSUBJECT], msg.Snippet) // fmt with label personal and threadId action := fmt.Sprintf(gmailDispatchUrl, "personal", msg.ThreadId) epoch := hdr.getEpoch() pushMsgMap[msg.ThreadId] = plugins.NewStandardPushMessage(summary, body, action, avatarPath, epoch) } else { log.Print("gmail plugin ", p.accountId, ": skipping message id ", msg.Id, " with date ", msgStamp, " older than ", timeDelta) } } pushMsg := make([]*plugins.PushMessage, 0, len(pushMsgMap)) for _, v := range pushMsgMap { pushMsg = append(pushMsg, v) } return pushMsg, nil } func (p *GmailPlugin) handleOverflow(pushMsg []*plugins.PushMessage) *plugins.PushMessage { // TODO it would probably be better to grab the estimate that google returns in the message list. approxUnreadMessages := len(pushMsg) // TRANSLATORS: the %d refers to the number of new email messages. summary := fmt.Sprintf(gettext.Gettext("You have %d new messages"), approxUnreadMessages) body := "" // fmt with label personal and no threadId action := fmt.Sprintf(gmailDispatchUrl, "personal") epoch := time.Now().Unix() return plugins.NewStandardPushMessage(summary, body, action, "", epoch) } func (p *GmailPlugin) parseMessageListResponse(resp *http.Response) ([]message, error) { defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) if resp.StatusCode != http.StatusOK { var errResp errorResp if err := decoder.Decode(&errResp); err != nil { return nil, err } if errResp.Err.Code == 401 { return nil, plugins.ErrTokenExpired } return nil, &errResp } var messages messageList if err := decoder.Decode(&messages); err != nil { return nil, err } filteredMsg := p.messageListFilter(messages.Messages) return filteredMsg, nil } // messageListFilter returns a subset of unread messages where the subset // depends on not being in reportedIds. Before returning, reportedIds is // updated with the new list of unread messages. func (p *GmailPlugin) messageListFilter(messages []message) []message { sort.Sort(byId(messages)) var reportMsg []message var ids = make(reportedIdMap) for _, msg := range messages { if !p.reported(msg.Id) { reportMsg = append(reportMsg, msg) } ids[msg.Id] = time.Now() } p.reportedIds = ids p.reportedIds.persist(p.accountId) return reportMsg } func (p *GmailPlugin) parseMessageResponse(resp *http.Response) (message, error) { defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) if resp.StatusCode != http.StatusOK { var errResp errorResp if err := decoder.Decode(&errResp); err != nil { return message{}, err } return message{}, &errResp } var msg message if err := decoder.Decode(&msg); err != nil { return message{}, err } return msg, nil } func (p *GmailPlugin) requestMessage(id, accessToken string) (*http.Response, error) { u, err := baseUrl.Parse("messages/" + id) if err != nil { return nil, err } query := u.Query() // only request specific fields query.Add("fields", "snippet,threadId,id,payload/headers") // get the full message to get From and Subject from headers query.Add("format", "full") u.RawQuery = query.Encode() req, err := http.NewRequest("GET", u.String(), nil) if err != nil { return nil, err } req.Header.Set("Authorization", "Bearer "+accessToken) return http.DefaultClient.Do(req) } func (p *GmailPlugin) requestMessageList(accessToken string) (*http.Response, error) { u, err := baseUrl.Parse("messages") if err != nil { return nil, err } query := u.Query() // get all unread inbox emails received after // the last time we checked. If this is the first // time we check, get unread emails after timeDelta query.Add("q", fmt.Sprintf("is:unread in:inbox newer_than:%s", relativeTimeDelta)) u.RawQuery = query.Encode() req, err := http.NewRequest("GET", u.String(), nil) if err != nil { return nil, err } req.Header.Set("Authorization", "Bearer "+accessToken) return http.DefaultClient.Do(req) } account-polld-0.1+16.04.20160308.1/plugins/gmail/api.go0000644000015600001650000000674312667556700022523 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package gmail import ( "fmt" "time" "launchpad.net/account-polld/plugins" ) const gmailTime = "Mon, 2 Jan 2006 15:04:05 -0700" type pushes map[string]*plugins.PushMessage type headers map[string]string // messageList holds a response to call to Users.messages: list // defined in https://developers.google.com/gmail/api/v1/reference/users/messages/list type messageList struct { // Messages holds a list of message. Messages []message `json:"messages"` // NextPageToken is used to retrieve the next page of results in the list. NextPageToken string `json:"nextPageToken"` // ResultSizeEstimage is the estimated total number of results. ResultSizeEstimage uint64 `json:"resultSizeEstimate"` } // message holds a partial response for a Users.messages. // The full definition of a message is defined in // https://developers.google.com/gmail/api/v1/reference/users/messages#resource type message struct { // Id is the immutable ID of the message. Id string `json:"id"` // ThreadId is the ID of the thread the message belongs to. ThreadId string `json:"threadId"` // HistoryId is the ID of the last history record that modified // this message. HistoryId string `json:"historyId"` // Snippet is a short part of the message text. This text is // used for the push message summary. Snippet string `json:"snippet"` // Payload represents the message payload. Payload payload `json:"payload"` } func (m message) String() string { return fmt.Sprintf("Id: %d, snippet: '%s'\n", m.Id, m.Snippet[:10]) } // ById implements sort.Interface for []message based on // the Id field. type byId []message func (m byId) Len() int { return len(m) } func (m byId) Swap(i, j int) { m[i], m[j] = m[j], m[i] } func (m byId) Less(i, j int) bool { return m[i].Id < m[j].Id } // payload represents the message payload. type payload struct { Headers []messageHeader `json:"headers"` } func (p *payload) mapHeaders() headers { headers := make(map[string]string) for _, hdr := range p.Headers { headers[hdr.Name] = hdr.Value } return headers } func (hdr headers) getTimestamp() time.Time { timestamp, ok := hdr[hdrDATE] if !ok { return time.Now() } if t, err := time.Parse(gmailTime, timestamp); err == nil { return t } return time.Now() } func (hdr headers) getEpoch() int64 { return hdr.getTimestamp().Unix() } // messageHeader represents the message headers. type messageHeader struct { Name string `json:"name"` Value string `json:"value"` } type errorResp struct { Err struct { Code uint64 `json:"code"` Message string `json:"message"` Errors []struct { Domain string `json:"domain"` Reason string `json:"reason"` Message string `json:"message"` } `json:"errors"` } `json:"error"` } func (err *errorResp) Error() string { return fmt.Sprint("backend response:", err.Err.Message) } const ( hdrDATE = "Date" hdrSUBJECT = "Subject" hdrFROM = "From" ) account-polld-0.1+16.04.20160308.1/plugins/twitter/0000755000015600001650000000000012667557117022025 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/plugins/twitter/oauth/0000755000015600001650000000000012667557117023145 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/plugins/twitter/oauth/README.markdown0000644000015600001650000000160712667556700025647 0ustar pbuserpbgroup00000000000000# Go-OAuth Go-OAuth is a [Go](http://golang.org/) client for the OAuth 1.0, OAuth 1.0a and RFC 5849. ## Installation Use the [go tool](http://weekly.golang.org/cmd/go/) to install Go-OAuth: go get github.com/garyburd/go-oauth/oauth ##License Go-OAuth is available under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). ## Documentation - [Reference](http://godoc.org/github.com/garyburd/go-oauth/oauth) - [Dropbox Example](http://github.com/garyburd/go-oauth/tree/master/examples/dropbox) - [Netflix Example](http://github.com/garyburd/go-oauth/tree/master/examples/netflix) - [SmugMug Example](https://github.com/garyburd/go-oauth/tree/master/examples/smugmug) - [Twitter Example](http://github.com/garyburd/go-oauth/tree/master/examples/twitter) - [Twitter Example on App Engine](http://github.com/garyburd/go-oauth/tree/master/examples/appengine) account-polld-0.1+16.04.20160308.1/plugins/twitter/oauth/oauth_test.go0000644000015600001650000002136012667556700025652 0ustar pbuserpbgroup00000000000000// Copyright 2010 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package oauth import ( "bytes" "net/url" "testing" ) func parseURL(urlStr string) *url.URL { u, _ := url.Parse(urlStr) return u } var oauthTests = []struct { method string url *url.URL appParams url.Values nonce string timestamp string clientCredentials Credentials credentials Credentials base string header string }{ { // Simple example from Twitter OAuth tool "GET", parseURL("https://api.twitter.com/1/"), url.Values{"page": {"10"}}, "8067e8abc6bdca2006818132445c8f4c", "1355795903", Credentials{"kMViZR2MHk2mM7hUNVw9A", "56Fgl58yOfqXOhHXX0ybvOmSnPQFvR2miYmm30A"}, Credentials{"10212-JJ3Zc1A49qSMgdcAO2GMOpW9l7A348ESmhjmOBOU", "yF75mvq4LZMHj9O0DXwoC3ZxUnN1ptvieThYuOAYM"}, `GET&https%3A%2F%2Fapi.twitter.com%2F1%2F&oauth_consumer_key%3DkMViZR2MHk2mM7hUNVw9A%26oauth_nonce%3D8067e8abc6bdca2006818132445c8f4c%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1355795903%26oauth_token%3D10212-JJ3Zc1A49qSMgdcAO2GMOpW9l7A348ESmhjmOBOU%26oauth_version%3D1.0%26page%3D10`, `OAuth oauth_consumer_key="kMViZR2MHk2mM7hUNVw9A", oauth_nonce="8067e8abc6bdca2006818132445c8f4c", oauth_signature="o5cx1ggJrY9ognZuVVeUwglKV8U%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1355795903", oauth_token="10212-JJ3Zc1A49qSMgdcAO2GMOpW9l7A348ESmhjmOBOU", oauth_version="1.0"`, }, { // Test case and port insensitivity. "GeT", parseURL("https://apI.twItter.com:443/1/"), url.Values{"page": {"10"}}, "8067e8abc6bdca2006818132445c8f4c", "1355795903", Credentials{"kMViZR2MHk2mM7hUNVw9A", "56Fgl58yOfqXOhHXX0ybvOmSnPQFvR2miYmm30A"}, Credentials{"10212-JJ3Zc1A49qSMgdcAO2GMOpW9l7A348ESmhjmOBOU", "yF75mvq4LZMHj9O0DXwoC3ZxUnN1ptvieThYuOAYM"}, `GET&https%3A%2F%2Fapi.twitter.com%2F1%2F&oauth_consumer_key%3DkMViZR2MHk2mM7hUNVw9A%26oauth_nonce%3D8067e8abc6bdca2006818132445c8f4c%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1355795903%26oauth_token%3D10212-JJ3Zc1A49qSMgdcAO2GMOpW9l7A348ESmhjmOBOU%26oauth_version%3D1.0%26page%3D10`, `OAuth oauth_consumer_key="kMViZR2MHk2mM7hUNVw9A", oauth_nonce="8067e8abc6bdca2006818132445c8f4c", oauth_signature="o5cx1ggJrY9ognZuVVeUwglKV8U%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1355795903", oauth_token="10212-JJ3Zc1A49qSMgdcAO2GMOpW9l7A348ESmhjmOBOU", oauth_version="1.0"`, }, { // Example generated using the Netflix OAuth tool. "GET", parseURL("http://api-public.netflix.com/catalog/titles"), url.Values{"term": {"Dark Knight"}, "count": {"2"}}, "1234", "1355850443", Credentials{"apiKey001", "sharedSecret002"}, Credentials{"accessToken003", "accessSecret004"}, `GET&http%3A%2F%2Fapi-public.netflix.com%2Fcatalog%2Ftitles&count%3D2%26oauth_consumer_key%3DapiKey001%26oauth_nonce%3D1234%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1355850443%26oauth_token%3DaccessToken003%26oauth_version%3D1.0%26term%3DDark%2520Knight`, `OAuth oauth_consumer_key="apiKey001", oauth_nonce="1234", oauth_signature="0JAoaqt6oz6TJx8N%2B06XmhPjcOs%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1355850443", oauth_token="accessToken003", oauth_version="1.0"`, }, { // Test special characters in form values. "GET", parseURL("http://PHOTOS.example.net:8001/Photos"), url.Values{"photo size": {"300%"}, "title": {"Back of $100 Dollars Bill"}}, "kllo~9940~pd9333jh", "1191242096", Credentials{"dpf43f3++p+#2l4k3l03", "secret01"}, Credentials{"nnch734d(0)0sl2jdk", "secret02"}, "GET&http%3A%2F%2Fphotos.example.net%3A8001%2FPhotos&oauth_consumer_key%3Ddpf43f3%252B%252Bp%252B%25232l4k3l03%26oauth_nonce%3Dkllo~9940~pd9333jh%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26oauth_token%3Dnnch734d%25280%25290sl2jdk%26oauth_version%3D1.0%26photo%2520size%3D300%2525%26title%3DBack%2520of%2520%2524100%2520Dollars%2520Bill", `OAuth oauth_consumer_key="dpf43f3%2B%2Bp%2B%232l4k3l03", oauth_nonce="kllo~9940~pd9333jh", oauth_signature="n1UAoQy2PoIYizZUiWvkdCxM3P0%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1191242096", oauth_token="nnch734d%280%290sl2jdk", oauth_version="1.0"`, }, { // Test special characters in path, multiple values for same key in form. "GET", parseURL("http://EXAMPLE.COM:80/Space%20Craft"), url.Values{"name": {"value", "value"}}, "Ix4U1Ei3RFL", "1327384901", Credentials{"abcd", "efgh"}, Credentials{"ijkl", "mnop"}, "GET&http%3A%2F%2Fexample.com%2FSpace%2520Craft&name%3Dvalue%26name%3Dvalue%26oauth_consumer_key%3Dabcd%26oauth_nonce%3DIx4U1Ei3RFL%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1327384901%26oauth_token%3Dijkl%26oauth_version%3D1.0", `OAuth oauth_consumer_key="abcd", oauth_nonce="Ix4U1Ei3RFL", oauth_signature="TZZ5u7qQorLnmKs%2Biqunb8gqkh4%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1327384901", oauth_token="ijkl", oauth_version="1.0"`, }, { // Test with query string in URL. "GET", parseURL("http://EXAMPLE.COM:80/Space%20Craft?name=value"), url.Values{"name": {"value"}}, "Ix4U1Ei3RFL", "1327384901", Credentials{"abcd", "efgh"}, Credentials{"ijkl", "mnop"}, "GET&http%3A%2F%2Fexample.com%2FSpace%2520Craft&name%3Dvalue%26name%3Dvalue%26oauth_consumer_key%3Dabcd%26oauth_nonce%3DIx4U1Ei3RFL%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1327384901%26oauth_token%3Dijkl%26oauth_version%3D1.0", `OAuth oauth_consumer_key="abcd", oauth_nonce="Ix4U1Ei3RFL", oauth_signature="TZZ5u7qQorLnmKs%2Biqunb8gqkh4%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1327384901", oauth_token="ijkl", oauth_version="1.0"`, }, { // Test "/" in form value. "POST", parseURL("https://stream.twitter.com/1.1/statuses/filter.json"), url.Values{"track": {"example.com/abcd"}}, "bf2cb6d611e59f99103238fc9a3bb8d8", "1362434376", Credentials{"consumer_key", "consumer_secret"}, Credentials{"token", "secret"}, "POST&https%3A%2F%2Fstream.twitter.com%2F1.1%2Fstatuses%2Ffilter.json&oauth_consumer_key%3Dconsumer_key%26oauth_nonce%3Dbf2cb6d611e59f99103238fc9a3bb8d8%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1362434376%26oauth_token%3Dtoken%26oauth_version%3D1.0%26track%3Dexample.com%252Fabcd", `OAuth oauth_consumer_key="consumer_key", oauth_nonce="bf2cb6d611e59f99103238fc9a3bb8d8", oauth_signature="LcxylEOnNdgoKSJi7jX07mxcvfM%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1362434376", oauth_token="token", oauth_version="1.0"`, }, { // Test "/" in query string "POST", parseURL("https://stream.twitter.com/1.1/statuses/filter.json?track=example.com/query"), url.Values{}, "884275759fbab914654b50ae643c563a", "1362435218", Credentials{"consumer_key", "consumer_secret"}, Credentials{"token", "secret"}, "POST&https%3A%2F%2Fstream.twitter.com%2F1.1%2Fstatuses%2Ffilter.json&oauth_consumer_key%3Dconsumer_key%26oauth_nonce%3D884275759fbab914654b50ae643c563a%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1362435218%26oauth_token%3Dtoken%26oauth_version%3D1.0%26track%3Dexample.com%252Fquery", `OAuth oauth_consumer_key="consumer_key", oauth_nonce="884275759fbab914654b50ae643c563a", oauth_signature="OAldqvRrKDXRGZ9BqSi2CqeVH0g%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1362435218", oauth_token="token", oauth_version="1.0"`, }, } func TestBaseString(t *testing.T) { for _, ot := range oauthTests { oauthParams := map[string]string{ "oauth_consumer_key": ot.clientCredentials.Token, "oauth_nonce": ot.nonce, "oauth_timestamp": ot.timestamp, "oauth_token": ot.credentials.Token, "oauth_signature_method": "HMAC-SHA1", "oauth_version": "1.0", } var buf bytes.Buffer writeBaseString(&buf, ot.method, ot.url, ot.appParams, oauthParams) base := buf.String() if base != ot.base { t.Errorf("base string for %s %s\n = %q,\n want %q", ot.method, ot.url, base, ot.base) } } } func TestAuthorizationHeader(t *testing.T) { defer func() { testingNonce = "" testingTimestamp = "" }() for _, ot := range oauthTests { c := Client{Credentials: ot.clientCredentials} testingNonce = ot.nonce testingTimestamp = ot.timestamp header := c.AuthorizationHeader(&ot.credentials, ot.method, ot.url, ot.appParams) if header != ot.header { t.Errorf("authorization header for %s %s\ngot: %s\nwant: %s", ot.method, ot.url, header, ot.header) } } } account-polld-0.1+16.04.20160308.1/plugins/twitter/oauth/oauth.go0000644000015600001650000003560512667556700024622 0ustar pbuserpbgroup00000000000000// Copyright 2010 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. // Package oauth is consumer interface for OAuth 1.0, OAuth 1.0a and RFC 5849. // // Redirection-based Authorization // // This section outlines how to use the oauth package in redirection-based // authorization (http://tools.ietf.org/html/rfc5849#section-2). // // Step 1: Create a Client using credentials and URIs provided by the server. // The Client can be initialized once at application startup and stored in a // package-level variable. // // Step 2: Request temporary credentials using the Client // RequestTemporaryCredentials method. The callbackURL parameter is the URL of // the callback handler in step 4. Save the returned credential secret so that // it can be later found using credential token as a key. The secret can be // stored in a database keyed by the token. Another option is to store the // token and secret in session storage or a cookie. // // Step 3: Redirect the user to URL returned from AuthorizationURL method. The // AuthorizationURL method uses the temporary credentials from step 2 and other // parameters as specified by the server. // // Step 4: The server redirects back to the callback URL specified in step 2 // with the temporary token and a verifier. Use the temporary token to find the // temporary secret saved in step 2. Using the temporary token, temporary // secret and verifier, request token credentials using the client RequestToken // method. Save the returned credentials for later use in the application. // // Signing Requests // // The Client type has two low-level methods for signing requests, SignForm and // AuthorizationHeader. // // The SignForm method adds an OAuth signature to a form. The application makes // an authenticated request by encoding the modified form to the query string // or request body. // // The AuthorizationHeader method returns an Authorization header value with // the OAuth signature. The application makes an authenticated request by // adding the Authorization header to the request. The AuthorizationHeader // method is the only way to correctly sign a request if the application sets // the URL Opaque field when making a request. // // The Get and Post methods sign and invoke a request using the supplied // net/http Client. These methods are easy to use, but not as flexible as // constructing a request using one of the low-level methods. package oauth import ( "bytes" "crypto/hmac" "crypto/rand" "crypto/sha1" "encoding/base64" "encoding/binary" "errors" "fmt" "io" "io/ioutil" "net/http" "net/url" "sort" "strconv" "strings" "sync" "time" ) // noscape[b] is true if b should not be escaped per section 3.6 of the RFC. var noEscape = [256]bool{ 'A': true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, 'a': true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, '0': true, true, true, true, true, true, true, true, true, true, '-': true, '.': true, '_': true, '~': true, } // encode encodes string per section 3.6 of the RFC. If double is true, then // the encoding is applied twice. func encode(s string, double bool) []byte { // Compute size of result. m := 3 if double { m = 5 } n := 0 for i := 0; i < len(s); i++ { if noEscape[s[i]] { n += 1 } else { n += m } } p := make([]byte, n) // Encode it. j := 0 for i := 0; i < len(s); i++ { b := s[i] if noEscape[b] { p[j] = b j += 1 } else if double { p[j] = '%' p[j+1] = '2' p[j+2] = '5' p[j+3] = "0123456789ABCDEF"[b>>4] p[j+4] = "0123456789ABCDEF"[b&15] j += 5 } else { p[j] = '%' p[j+1] = "0123456789ABCDEF"[b>>4] p[j+2] = "0123456789ABCDEF"[b&15] j += 3 } } return p } type keyValue struct{ key, value []byte } type byKeyValue []keyValue func (p byKeyValue) Len() int { return len(p) } func (p byKeyValue) Swap(i, j int) { p[i], p[j] = p[j], p[i] } func (p byKeyValue) Less(i, j int) bool { sgn := bytes.Compare(p[i].key, p[j].key) if sgn == 0 { sgn = bytes.Compare(p[i].value, p[j].value) } return sgn < 0 } func (p byKeyValue) appendValues(values url.Values) byKeyValue { for k, vs := range values { k := encode(k, true) for _, v := range vs { v := encode(v, true) p = append(p, keyValue{k, v}) } } return p } // writeBaseString writes method, url, and params to w using the OAuth signature // base string computation described in section 3.4.1 of the RFC. func writeBaseString(w io.Writer, method string, u *url.URL, form url.Values, oauthParams map[string]string) { // Method w.Write(encode(strings.ToUpper(method), false)) w.Write([]byte{'&'}) // URL scheme := strings.ToLower(u.Scheme) host := strings.ToLower(u.Host) uNoQuery := *u uNoQuery.RawQuery = "" path := uNoQuery.RequestURI() switch { case scheme == "http" && strings.HasSuffix(host, ":80"): host = host[:len(host)-len(":80")] case scheme == "https" && strings.HasSuffix(host, ":443"): host = host[:len(host)-len(":443")] } w.Write(encode(scheme, false)) w.Write(encode("://", false)) w.Write(encode(host, false)) w.Write(encode(path, false)) w.Write([]byte{'&'}) // Create sorted slice of encoded parameters. Parameter keys and values are // double encoded in a single step. This is safe because double encoding // does not change the sort order. queryParams := u.Query() p := make(byKeyValue, 0, len(form)+len(queryParams)+len(oauthParams)) p = p.appendValues(form) p = p.appendValues(queryParams) for k, v := range oauthParams { p = append(p, keyValue{encode(k, true), encode(v, true)}) } sort.Sort(p) // Write the parameters. encodedAmp := encode("&", false) encodedEqual := encode("=", false) sep := false for _, kv := range p { if sep { w.Write(encodedAmp) } else { sep = true } w.Write(kv.key) w.Write(encodedEqual) w.Write(kv.value) } } var ( nonceLock sync.Mutex nonceCounter uint64 ) // nonce returns a unique string. func nonce() string { nonceLock.Lock() defer nonceLock.Unlock() if nonceCounter == 0 { binary.Read(rand.Reader, binary.BigEndian, &nonceCounter) } result := strconv.FormatUint(nonceCounter, 16) nonceCounter += 1 return result } // oauthParams returns the OAuth request parameters for the given credentials, // method, URL and application params. See // http://tools.ietf.org/html/rfc5849#section-3.4 for more information about // signatures. func oauthParams(clientCredentials *Credentials, credentials *Credentials, method string, u *url.URL, form url.Values) map[string]string { oauthParams := map[string]string{ "oauth_consumer_key": clientCredentials.Token, "oauth_signature_method": "HMAC-SHA1", "oauth_timestamp": strconv.FormatInt(time.Now().Unix(), 10), "oauth_version": "1.0", "oauth_nonce": nonce(), } if credentials != nil { oauthParams["oauth_token"] = credentials.Token } if testingNonce != "" { oauthParams["oauth_nonce"] = testingNonce } if testingTimestamp != "" { oauthParams["oauth_timestamp"] = testingTimestamp } var key bytes.Buffer key.Write(encode(clientCredentials.Secret, false)) key.WriteByte('&') if credentials != nil { key.Write(encode(credentials.Secret, false)) } h := hmac.New(sha1.New, key.Bytes()) writeBaseString(h, method, u, form, oauthParams) sum := h.Sum(nil) encodedSum := make([]byte, base64.StdEncoding.EncodedLen(len(sum))) base64.StdEncoding.Encode(encodedSum, sum) oauthParams["oauth_signature"] = string(encodedSum) return oauthParams } // Client represents an OAuth client. type Client struct { Credentials Credentials TemporaryCredentialRequestURI string // Also known as request token URL. ResourceOwnerAuthorizationURI string // Also known as authorization URL. TokenRequestURI string // Also known as access token URL. } // Credentials represents client, temporary and token credentials. type Credentials struct { Token string // Also known as consumer key or access token. Secret string // Also known as consumer secret or access token secret. } var ( testingTimestamp string testingNonce string ) // SignForm adds an OAuth signature to form. The urlStr argument must not // include a query string. // // See http://tools.ietf.org/html/rfc5849#section-3.5.2 for // information about transmitting OAuth parameters in a request body and // http://tools.ietf.org/html/rfc5849#section-3.5.2 for information about // transmitting OAuth parameters in a query string. func (c *Client) SignForm(credentials *Credentials, method, urlStr string, form url.Values) error { u, err := url.Parse(urlStr) switch { case err != nil: return err case u.RawQuery != "": return errors.New("oauth: urlStr argument to SignForm must not include a query string") } for k, v := range oauthParams(&c.Credentials, credentials, method, u, form) { form.Set(k, v) } return nil } // SignParam is deprecated. Use SignForm instead. func (c *Client) SignParam(credentials *Credentials, method, urlStr string, params url.Values) { u, _ := url.Parse(urlStr) u.RawQuery = "" for k, v := range oauthParams(&c.Credentials, credentials, method, u, params) { params.Set(k, v) } } // AuthorizationHeader returns the HTTP authorization header value for given // method, URL and parameters. // // See http://tools.ietf.org/html/rfc5849#section-3.5.1 for information about // transmitting OAuth parameters in an HTTP request header. func (c *Client) AuthorizationHeader(credentials *Credentials, method string, u *url.URL, params url.Values) string { p := oauthParams(&c.Credentials, credentials, method, u, params) var buf bytes.Buffer buf.WriteString(`OAuth oauth_consumer_key="`) buf.Write(encode(p["oauth_consumer_key"], false)) buf.WriteString(`", oauth_nonce="`) buf.Write(encode(p["oauth_nonce"], false)) buf.WriteString(`", oauth_signature="`) buf.Write(encode(p["oauth_signature"], false)) buf.WriteString(`", oauth_signature_method="HMAC-SHA1", oauth_timestamp="`) buf.Write(encode(p["oauth_timestamp"], false)) if t, ok := p["oauth_token"]; ok { buf.WriteString(`", oauth_token="`) buf.Write(encode(t, false)) } buf.WriteString(`", oauth_version="1.0"`) return buf.String() } // Get issues a GET to the specified URL with form added as a query string. func (c *Client) Get(client *http.Client, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) { req, err := http.NewRequest("GET", urlStr, nil) if err != nil { return nil, err } if req.URL.RawQuery != "" { return nil, errors.New("oauth: url must not contain a query string") } req.Header.Set("Authorization", c.AuthorizationHeader(credentials, "GET", req.URL, form)) req.URL.RawQuery = form.Encode() return client.Do(req) } func (c *Client) do(client *http.Client, method string, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) { req, err := http.NewRequest(method, urlStr, strings.NewReader(form.Encode())) if err != nil { return nil, err } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("Authorization", c.AuthorizationHeader(credentials, method, req.URL, form)) return client.Do(req) } // Post issues a POST with the specified form. func (c *Client) Post(client *http.Client, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) { return c.do(client, "POST", credentials, urlStr, form) } // Delete issues a DELETE with the specified form. func (c *Client) Delete(client *http.Client, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) { return c.do(client, "DELETE", credentials, urlStr, form) } // Put issues a PUT with the specified form. func (c *Client) Put(client *http.Client, credentials *Credentials, urlStr string, form url.Values) (*http.Response, error) { return c.do(client, "PUT", credentials, urlStr, form) } func (c *Client) request(client *http.Client, credentials *Credentials, urlStr string, params url.Values) (*Credentials, url.Values, error) { c.SignParam(credentials, "POST", urlStr, params) resp, err := client.PostForm(urlStr, params) if err != nil { return nil, nil, err } p, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { return nil, nil, err } if resp.StatusCode != 200 && resp.StatusCode != 201 { return nil, nil, fmt.Errorf("OAuth server status %d, %s", resp.StatusCode, string(p)) } m, err := url.ParseQuery(string(p)) if err != nil { return nil, nil, err } tokens := m["oauth_token"] if len(tokens) == 0 || tokens[0] == "" { return nil, nil, errors.New("oauth: token missing from server result") } secrets := m["oauth_token_secret"] if len(secrets) == 0 { // allow "" as a valid secret. return nil, nil, errors.New("oauth: secret missing from server result") } return &Credentials{Token: tokens[0], Secret: secrets[0]}, m, nil } // RequestTemporaryCredentials requests temporary credentials from the server. // See http://tools.ietf.org/html/rfc5849#section-2.1 for information about // temporary credentials. func (c *Client) RequestTemporaryCredentials(client *http.Client, callbackURL string, additionalParams url.Values) (*Credentials, error) { params := make(url.Values) for k, vs := range additionalParams { params[k] = vs } if callbackURL != "" { params.Set("oauth_callback", callbackURL) } credentials, _, err := c.request(client, nil, c.TemporaryCredentialRequestURI, params) return credentials, err } // RequestToken requests token credentials from the server. See // http://tools.ietf.org/html/rfc5849#section-2.3 for information about token // credentials. func (c *Client) RequestToken(client *http.Client, temporaryCredentials *Credentials, verifier string) (*Credentials, url.Values, error) { params := make(url.Values) if verifier != "" { params.Set("oauth_verifier", verifier) } credentials, vals, err := c.request(client, temporaryCredentials, c.TokenRequestURI, params) if err != nil { return nil, nil, err } return credentials, vals, nil } // AuthorizationURL returns the URL for resource owner authorization. See // http://tools.ietf.org/html/rfc5849#section-2.2 for information about // resource owner authorization. func (c *Client) AuthorizationURL(temporaryCredentials *Credentials, additionalParams url.Values) string { params := make(url.Values) for k, vs := range additionalParams { params[k] = vs } params.Set("oauth_token", temporaryCredentials.Token) return c.ResourceOwnerAuthorizationURI + "?" + params.Encode() } account-polld-0.1+16.04.20160308.1/plugins/twitter/oauth/examples_test.go0000644000015600001650000000333712667556700026354 0ustar pbuserpbgroup00000000000000// Copyright 2013 Gary Burd // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. package oauth_test import ( "net/http" "net/url" "strings" "launchpad.net/account-polld/plugins/twitter/oauth" // "github.com/garyburd/go-oauth/oauth" ) // This example shows how to sign a request when the URL Opaque field is used. // See the note at http://golang.org/pkg/net/url/#URL for information on the // use of the URL Opaque field. func ExampleClient_AuthorizationHeader(client *oauth.Client, credentials *oauth.Credentials) error { form := url.Values{"maxResults": {"100"}} // The last element of path contains a "/". path := "/document/encoding%2gizp" // Create the request with the temporary path "/". req, err := http.NewRequest("GET", "http://api.example.com/", strings.NewReader(form.Encode())) if err != nil { return err } // Overwrite the temporary path with the actual request path. req.URL.Opaque = path // Sign the request. req.Header.Set("Authorization", client.AuthorizationHeader(credentials, "GET", req.URL, form)) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") resp, err := http.DefaultClient.Do(req) if err != nil { return err } defer resp.Body.Close() // process the response return nil } account-polld-0.1+16.04.20160308.1/plugins/twitter/twitter_test.go0000644000015600001650000003754212667556700025125 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package twitter import ( "bytes" "io" "net/http" "testing" . "launchpad.net/gocheck" "launchpad.net/account-polld/plugins" ) type S struct{} func init() { Suite(S{}) } func TestAll(t *testing.T) { TestingT(t) } // closeWraper adds a dummy Close() method to a reader type closeWrapper struct { io.Reader } func (r closeWrapper) Close() error { return nil } const ( errorBody = ` { "errors": [ { "message":"Sorry, that page does not exist", "code":34 } ] }` tokenExpiredErrorBody = ` { "errors": [ { "message":"Invalid or expired token", "code":89 } ] }` statusesBody = ` [ { "coordinates": null, "favorited": false, "truncated": false, "created_at": "Mon Sep 03 13:24:14 +0000 2012", "id_str": "242613977966850048", "entities": { "urls": [ ], "hashtags": [ ], "user_mentions": [ { "name": "Jason Costa", "id_str": "14927800", "id": 14927800, "indices": [ 0, 11 ], "screen_name": "jasoncosta" }, { "name": "Matt Harris", "id_str": "777925", "id": 777925, "indices": [ 12, 26 ], "screen_name": "themattharris" }, { "name": "ThinkWall", "id_str": "117426578", "id": 117426578, "indices": [ 109, 119 ], "screen_name": "thinkwall" } ] }, "in_reply_to_user_id_str": "14927800", "contributors": null, "text": "@jasoncosta @themattharris Hey! Going to be in Frisco in October. Was hoping to have a meeting to talk about @thinkwall if you're around?", "retweet_count": 0, "in_reply_to_status_id_str": null, "id": 242613977966850048, "geo": null, "retweeted": false, "in_reply_to_user_id": 14927800, "place": null, "user": { "profile_sidebar_fill_color": "EEEEEE", "profile_sidebar_border_color": "000000", "profile_background_tile": false, "name": "Andrew Spode Miller", "profile_image_url": "http://a0.twimg.com/profile_images/1227466231/spode-balloon-medium_normal.jpg", "created_at": "Mon Sep 22 13:12:01 +0000 2008", "location": "London via Gravesend", "follow_request_sent": false, "profile_link_color": "F31B52", "is_translator": false, "id_str": "16402947", "entities": { "url": { "urls": [ { "expanded_url": null, "url": "http://www.linkedin.com/in/spode", "indices": [ 0, 32 ] } ] }, "description": { "urls": [ ] } }, "default_profile": false, "contributors_enabled": false, "favourites_count": 16, "url": "http://www.linkedin.com/in/spode", "profile_image_url_https": "https://si0.twimg.com/profile_images/1227466231/spode-balloon-medium_normal.jpg", "utc_offset": 0, "id": 16402947, "profile_use_background_image": false, "listed_count": 129, "profile_text_color": "262626", "lang": "en", "followers_count": 2013, "protected": false, "notifications": null, "profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/16420220/twitter-background-final.png", "profile_background_color": "FFFFFF", "verified": false, "geo_enabled": true, "time_zone": "London", "description": "Co-Founder/Dev (PHP/jQuery) @justFDI. Run @thinkbikes and @thinkwall for events. Ex tech journo, helps run @uktjpr. Passion for Linux and customises everything.", "default_profile_image": false, "profile_background_image_url": "http://a0.twimg.com/profile_background_images/16420220/twitter-background-final.png", "statuses_count": 11550, "friends_count": 770, "following": null, "show_all_inline_media": true, "screen_name": "spode" }, "in_reply_to_screen_name": "jasoncosta", "source": "JournoTwit", "in_reply_to_status_id": null }, { "coordinates": { "coordinates": [ 121.0132101, 14.5191613 ], "type": "Point" }, "favorited": false, "truncated": false, "created_at": "Mon Sep 03 08:08:02 +0000 2012", "id_str": "242534402280783873", "entities": { "urls": [ ], "hashtags": [ { "text": "twitter", "indices": [ 49, 57 ] } ], "user_mentions": [ { "name": "Jason Costa", "id_str": "14927800", "id": 14927800, "indices": [ 14, 25 ], "screen_name": "jasoncosta" } ] }, "in_reply_to_user_id_str": null, "contributors": null, "text": "Got the shirt @jasoncosta thanks man! Loving the #twitter bird on the shirt :-)", "retweet_count": 0, "in_reply_to_status_id_str": null, "id": 242534402280783873, "geo": { "coordinates": [ 14.5191613, 121.0132101 ], "type": "Point" }, "retweeted": false, "in_reply_to_user_id": null, "place": null, "user": { "profile_sidebar_fill_color": "EFEFEF", "profile_sidebar_border_color": "EEEEEE", "profile_background_tile": true, "name": "Mikey", "profile_image_url": "http://a0.twimg.com/profile_images/1305509670/chatMikeTwitter_normal.png", "created_at": "Fri Jun 20 15:57:08 +0000 2008", "location": "Singapore", "follow_request_sent": false, "profile_link_color": "009999", "is_translator": false, "id_str": "15181205", "entities": { "url": { "urls": [ { "expanded_url": null, "url": "http://about.me/michaelangelo", "indices": [ 0, 29 ] } ] }, "description": { "urls": [ ] } }, "default_profile": false, "contributors_enabled": false, "favourites_count": 11, "url": "http://about.me/michaelangelo", "profile_image_url_https": "https://si0.twimg.com/profile_images/1305509670/chatMikeTwitter_normal.png", "utc_offset": 28800, "id": 15181205, "profile_use_background_image": true, "listed_count": 61, "profile_text_color": "333333", "lang": "en", "followers_count": 577, "protected": false, "notifications": null, "profile_background_image_url_https": "https://si0.twimg.com/images/themes/theme14/bg.gif", "profile_background_color": "131516", "verified": false, "geo_enabled": true, "time_zone": "Hong Kong", "description": "Android Applications Developer, Studying Martial Arts, Plays MTG, Food and movie junkie", "default_profile_image": false, "profile_background_image_url": "http://a0.twimg.com/images/themes/theme14/bg.gif", "statuses_count": 11327, "friends_count": 138, "following": null, "show_all_inline_media": true, "screen_name": "mikedroid" }, "in_reply_to_screen_name": null, "source": "Twitter for Android", "in_reply_to_status_id": null } ]` directMessagesBody = ` [ { "created_at": "Mon Aug 27 17:21:03 +0000 2012", "entities": { "hashtags": [], "urls": [], "user_mentions": [] }, "id": 240136858829479936, "id_str": "240136858829479936", "recipient": { "contributors_enabled": false, "created_at": "Thu Aug 23 19:45:07 +0000 2012", "default_profile": false, "default_profile_image": false, "description": "Keep calm and test", "favourites_count": 0, "follow_request_sent": false, "followers_count": 0, "following": false, "friends_count": 10, "geo_enabled": true, "id": 776627022, "id_str": "776627022", "is_translator": false, "lang": "en", "listed_count": 0, "location": "San Francisco, CA", "name": "Mick Jagger", "notifications": false, "profile_background_color": "000000", "profile_background_image_url": "http://a0.twimg.com/profile_background_images/644522235/cdjlccey99gy36j3em67.jpeg", "profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/644522235/cdjlccey99gy36j3em67.jpeg", "profile_background_tile": true, "profile_image_url": "http://a0.twimg.com/profile_images/2550226257/y0ef5abcx5yrba8du0sk_normal.jpeg", "profile_image_url_https": "https://si0.twimg.com/profile_images/2550226257/y0ef5abcx5yrba8du0sk_normal.jpeg", "profile_link_color": "000000", "profile_sidebar_border_color": "000000", "profile_sidebar_fill_color": "000000", "profile_text_color": "000000", "profile_use_background_image": false, "protected": false, "screen_name": "s0c1alm3dia", "show_all_inline_media": false, "statuses_count": 0, "time_zone": "Pacific Time (US & Canada)", "url": "http://cnn.com", "utc_offset": -28800, "verified": false }, "recipient_id": 776627022, "recipient_screen_name": "s0c1alm3dia", "sender": { "contributors_enabled": true, "created_at": "Sat May 09 17:58:22 +0000 2009", "default_profile": false, "default_profile_image": false, "description": "I taught your phone that thing you like. The Mobile Partner Engineer @Twitter. ", "favourites_count": 584, "follow_request_sent": false, "followers_count": 10621, "following": false, "friends_count": 1181, "geo_enabled": true, "id": 38895958, "id_str": "38895958", "is_translator": false, "lang": "en", "listed_count": 190, "location": "San Francisco", "name": "Sean Cook", "notifications": false, "profile_background_color": "1A1B1F", "profile_background_image_url": "http://a0.twimg.com/profile_background_images/495742332/purty_wood.png", "profile_background_image_url_https": "https://si0.twimg.com/profile_background_images/495742332/purty_wood.png", "profile_background_tile": true, "profile_image_url": "http://a0.twimg.com/profile_images/1751506047/dead_sexy_normal.JPG", "profile_image_url_https": "https://si0.twimg.com/profile_images/1751506047/dead_sexy_normal.JPG", "profile_link_color": "2FC2EF", "profile_sidebar_border_color": "181A1E", "profile_sidebar_fill_color": "252429", "profile_text_color": "666666", "profile_use_background_image": true, "protected": false, "screen_name": "theSeanCook", "show_all_inline_media": true, "statuses_count": 2608, "time_zone": "Pacific Time (US & Canada)", "url": null, "utc_offset": -28800, "verified": false }, "sender_id": 38895958, "sender_screen_name": "theSeanCook", "text": "booyakasha" } ] ` ) func (s S) TestParseStatuses(c *C) { resp := &http.Response{ StatusCode: http.StatusOK, Body: closeWrapper{bytes.NewReader([]byte(statusesBody))}, } p := &twitterPlugin{} batch, err := p.parseStatuses(resp) c.Assert(err, IsNil) c.Assert(batch, NotNil) messages := batch.Messages c.Assert(len(messages), Equals, 2) c.Check(messages[0].Notification.Card.Summary, Equals, "Andrew Spode Miller. @spode") c.Check(messages[0].Notification.Card.Body, Equals, "@jasoncosta @themattharris Hey! Going to be in Frisco in October. Was hoping to have a meeting to talk about @thinkwall if you're around?") c.Check(messages[0].Notification.Card.Icon, Equals, "http://a0.twimg.com/profile_images/1227466231/spode-balloon-medium_normal.jpg") c.Assert(len(messages[0].Notification.Card.Actions), Equals, 1) c.Check(messages[0].Notification.Card.Actions[0], Equals, "https://mobile.twitter.com/spode/statuses/242613977966850048") c.Check(messages[1].Notification.Card.Summary, Equals, "Mikey. @mikedroid") c.Check(messages[1].Notification.Card.Body, Equals, "Got the shirt @jasoncosta thanks man! Loving the #twitter bird on the shirt :-)") c.Check(messages[1].Notification.Card.Icon, Equals, "http://a0.twimg.com/profile_images/1305509670/chatMikeTwitter_normal.png") c.Assert(len(messages[1].Notification.Card.Actions), Equals, 1) c.Check(messages[1].Notification.Card.Actions[0], Equals, "https://mobile.twitter.com/mikedroid/statuses/242534402280783873") c.Check(p.lastMentionId, Equals, int64(242613977966850048)) } func (s S) TestParseStatusesError(c *C) { resp := &http.Response{ StatusCode: http.StatusBadRequest, Body: closeWrapper{bytes.NewReader([]byte(errorBody))}, } p := &twitterPlugin{} messages, err := p.parseStatuses(resp) c.Check(messages, IsNil) c.Assert(err, Not(IsNil)) twErr := err.(*TwitterError) c.Assert(len(twErr.Errors), Equals, 1) c.Check(twErr.Errors[0].Message, Equals, "Sorry, that page does not exist") c.Check(twErr.Errors[0].Code, Equals, 34) } func (s S) TestParseStatusesTokenExpiredError(c *C) { resp := &http.Response{ StatusCode: http.StatusBadRequest, Body: closeWrapper{bytes.NewReader([]byte(tokenExpiredErrorBody))}, } p := &twitterPlugin{} messages, err := p.parseStatuses(resp) c.Check(messages, IsNil) c.Assert(err, Equals, plugins.ErrTokenExpired) } func (s S) TestParseDirectMessages(c *C) { resp := &http.Response{ StatusCode: http.StatusOK, Body: closeWrapper{bytes.NewReader([]byte(directMessagesBody))}, } p := &twitterPlugin{} batch, err := p.parseDirectMessages(resp) c.Assert(err, IsNil) c.Assert(batch, NotNil) messages := batch.Messages c.Assert(len(messages), Equals, 1) c.Check(messages[0].Notification.Card.Summary, Equals, "Sean Cook. @theSeanCook") c.Check(messages[0].Notification.Card.Body, Equals, "booyakasha") c.Check(messages[0].Notification.Card.Icon, Equals, "http://a0.twimg.com/profile_images/1751506047/dead_sexy_normal.JPG") c.Assert(len(messages[0].Notification.Card.Actions), Equals, 1) c.Check(messages[0].Notification.Card.Actions[0], Equals, "https://mobile.twitter.com/theSeanCook/messages") c.Check(p.lastDirectMessageId, Equals, int64(240136858829479936)) } func (s S) TestParseDirectMessagesError(c *C) { resp := &http.Response{ StatusCode: http.StatusBadRequest, Body: closeWrapper{bytes.NewReader([]byte(errorBody))}, } p := &twitterPlugin{} messages, err := p.parseDirectMessages(resp) c.Check(messages, IsNil) c.Assert(err, Not(IsNil)) twErr := err.(*TwitterError) c.Assert(len(twErr.Errors), Equals, 1) c.Check(twErr.Errors[0].Message, Equals, "Sorry, that page does not exist") c.Check(twErr.Errors[0].Code, Equals, 34) } func (s S) TestParseDirectMessagesTokenExpiredError(c *C) { resp := &http.Response{ StatusCode: http.StatusBadRequest, Body: closeWrapper{bytes.NewReader([]byte(tokenExpiredErrorBody))}, } p := &twitterPlugin{} messages, err := p.parseDirectMessages(resp) c.Check(messages, IsNil) c.Assert(err, Equals, plugins.ErrTokenExpired) } account-polld-0.1+16.04.20160308.1/plugins/twitter/twitter.go0000644000015600001650000002171712667556700024063 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package twitter import ( "encoding/json" "fmt" "net/http" "net/url" "sort" "strings" "time" "launchpad.net/account-polld/accounts" "launchpad.net/account-polld/gettext" "launchpad.net/account-polld/plugins" "launchpad.net/account-polld/plugins/twitter/oauth" // "github.com/garyburd/go-oauth/oauth" ) var baseUrl, _ = url.Parse("https://api.twitter.com/1.1/") const ( maxIndividualStatuses = 2 consolidatedStatusIndexStart = maxIndividualStatuses maxIndividualDirectMessages = 2 consolidatedDirectMessageIndexStart = maxIndividualDirectMessages twitterDispatchUrlBase = "https://mobile.twitter.com" ) type twitterPlugin struct { lastMentionId int64 lastDirectMessageId int64 bootstrap bool } func New() plugins.Plugin { return &twitterPlugin{} } func (p *twitterPlugin) ApplicationId() plugins.ApplicationId { return "com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter" } func (p *twitterPlugin) request(authData *accounts.AuthData, path string) (*http.Response, error) { // Resolve path relative to API base URL. u, err := baseUrl.Parse(path) if err != nil { return nil, err } query := u.Query() u.RawQuery = "" client := oauth.Client{ Credentials: oauth.Credentials{ Token: authData.ClientId, Secret: authData.ClientSecret, }, } token := &oauth.Credentials{ Token: authData.AccessToken, Secret: authData.TokenSecret, } return client.Get(http.DefaultClient, token, u.String(), query) } func (p *twitterPlugin) parseStatuses(resp *http.Response) (*plugins.PushMessageBatch, error) { defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) if resp.StatusCode != http.StatusOK { var result TwitterError if err := decoder.Decode(&result); err != nil { return nil, err } // Error code 89 is used for invalid or expired tokens. for _, e := range result.Errors { if e.Code == 89 { return nil, plugins.ErrTokenExpired } } return nil, &result } var statuses []status if err := decoder.Decode(&statuses); err != nil { return nil, err } sort.Sort(sort.Reverse(byStatusId(statuses))) if len(statuses) < 1 { return nil, nil } p.lastMentionId = statuses[0].Id pushMsg := make([]*plugins.PushMessage, len(statuses)) for i, s := range statuses { // TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. summary := fmt.Sprintf(gettext.Gettext("%s. @%s"), s.User.Name, s.User.ScreenName) action := fmt.Sprintf("%s/%s/statuses/%d", twitterDispatchUrlBase, s.User.ScreenName, s.Id) epoch := toEpoch(s.CreatedAt) pushMsg[i] = plugins.NewStandardPushMessage(summary, s.Text, action, s.User.Image, epoch) } return &plugins.PushMessageBatch{ Messages: pushMsg, Limit: maxIndividualStatuses, OverflowHandler: p.consolidateStatuses, Tag: "status", }, nil } func (p *twitterPlugin) consolidateStatuses(pushMsg []*plugins.PushMessage) *plugins.PushMessage { screennames := make([]string, len(pushMsg)) for i, m := range pushMsg { screennames[i] = m.Notification.Card.Summary } // TRANSLATORS: This represents a notification summary about more twitter mentions available summary := gettext.Gettext("Multiple more mentions") // TRANSLATORS: This represents a notification body with the comma separated twitter usernames body := fmt.Sprintf(gettext.Gettext("From %s"), strings.Join(screennames, ", ")) action := fmt.Sprintf("%s/i/connect", twitterDispatchUrlBase) epoch := time.Now().Unix() return plugins.NewStandardPushMessage(summary, body, action, "", epoch) } func (p *twitterPlugin) parseDirectMessages(resp *http.Response) (*plugins.PushMessageBatch, error) { defer resp.Body.Close() decoder := json.NewDecoder(resp.Body) if resp.StatusCode != http.StatusOK { var result TwitterError if err := decoder.Decode(&result); err != nil { return nil, err } // Error code 89 is used for invalid or expired tokens. for _, e := range result.Errors { if e.Code == 89 { return nil, plugins.ErrTokenExpired } } return nil, &result } var dms []directMessage if err := decoder.Decode(&dms); err != nil { return nil, err } sort.Sort(sort.Reverse(byDMId(dms))) if len(dms) < 1 { return nil, nil } p.lastDirectMessageId = dms[0].Id pushMsg := make([]*plugins.PushMessage, len(dms)) for i, m := range dms { // TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. summary := fmt.Sprintf(gettext.Gettext("%s. @%s"), m.Sender.Name, m.Sender.ScreenName) action := fmt.Sprintf("%s/%s/messages", twitterDispatchUrlBase, m.Sender.ScreenName) epoch := toEpoch(m.CreatedAt) pushMsg[i] = plugins.NewStandardPushMessage(summary, m.Text, action, m.Sender.Image, epoch) } return &plugins.PushMessageBatch{ Messages: pushMsg, Limit: maxIndividualDirectMessages, OverflowHandler: p.consolidateDirectMessages, Tag: "direct-message", }, nil } func (p *twitterPlugin) consolidateDirectMessages(pushMsg []*plugins.PushMessage) *plugins.PushMessage { senders := make([]string, len(pushMsg)) for i, m := range pushMsg { senders[i] = m.Notification.Card.Summary } // TRANSLATORS: This represents a notification summary about more twitter direct messages available summary := gettext.Gettext("Multiple direct messages available") // TRANSLATORS: This represents a notification body with the comma separated twitter usernames body := fmt.Sprintf(gettext.Gettext("From %s"), strings.Join(senders, ", ")) action := fmt.Sprintf("%s/messages", twitterDispatchUrlBase) epoch := time.Now().Unix() return plugins.NewStandardPushMessage(summary, body, action, "", epoch) } func (p *twitterPlugin) Poll(authData *accounts.AuthData) (batches []*plugins.PushMessageBatch, err error) { url := "statuses/mentions_timeline.json" if p.lastMentionId > 0 { url = fmt.Sprintf("%s?since_id=%d", url, p.lastMentionId) } resp, err := p.request(authData, url) if err != nil { return } statuses, err := p.parseStatuses(resp) if err != nil { return } url = "direct_messages.json" if p.lastDirectMessageId > 0 { url = fmt.Sprintf("%s?since_id=%d", url, p.lastDirectMessageId) } resp, err = p.request(authData, url) if err != nil { return } dms, err := p.parseDirectMessages(resp) if err != nil { return } if !p.bootstrap { p.bootstrap = true return nil, nil } if statuses != nil && len(statuses.Messages) > 0 { batches = append(batches, statuses) } if dms != nil && len(dms.Messages) > 0 { batches = append(batches, dms) } return } func toEpoch(timestamp string) int64 { if t, err := time.Parse(time.RubyDate, timestamp); err == nil { return t.Unix() } return time.Now().Unix() } // Status format is described here: // https://dev.twitter.com/docs/api/1.1/get/statuses/mentions_timeline type status struct { Id int64 `json:"id"` CreatedAt string `json:"created_at"` User user `json:"user"` Text string `json:"text"` } // ByStatusId implements sort.Interface for []status based on // the Id field. type byStatusId []status func (s byStatusId) Len() int { return len(s) } func (s byStatusId) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s byStatusId) Less(i, j int) bool { return s[i].Id < s[j].Id } // Direct message format is described here: // https://dev.twitter.com/docs/api/1.1/get/direct_messages type directMessage struct { Id int64 `json:"id"` CreatedAt string `json:"created_at"` Sender user `json:"sender"` Recipient user `json:"recipient"` Text string `json:"text"` } // ByStatusId implements sort.Interface for []status based on // the Id field. type byDMId []directMessage func (s byDMId) Len() int { return len(s) } func (s byDMId) Swap(i, j int) { s[i], s[j] = s[j], s[i] } func (s byDMId) Less(i, j int) bool { return s[i].Id < s[j].Id } type user struct { Id int64 `json:"id"` ScreenName string `json:"screen_name"` Name string `json:"name"` Image string `json:"profile_image_url"` } // The error response format is described here: // https://dev.twitter.com/docs/error-codes-responses type TwitterError struct { Errors []struct { Code int `json:"code"` Message string `json:"message"` } `json:"errors"` } func (err *TwitterError) Error() string { messages := make([]string, len(err.Errors)) for i := range err.Errors { messages[i] = err.Errors[i].Message } return strings.Join(messages, "\n") } account-polld-0.1+16.04.20160308.1/plugins/plugins.go0000644000015600001650000001631112667556721022335 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package plugins import ( "bufio" "encoding/json" "errors" "fmt" "os" "path/filepath" "reflect" "launchpad.net/account-polld/accounts" "launchpad.net/go-xdg/v0" ) func init() { cmdName = filepath.Base(os.Args[0]) } // Plugin is an interface which the plugins will adhere to for the poll // daemon to interact with. // // Poll interacts with the backend service with the means the plugin defines // and returns a list of Notifications to send to the Push service. If an // error occurs and is returned the daemon can decide to throttle the service. // // ApplicationId returns the APP_ID of the delivery target for Post Office. type Plugin interface { ApplicationId() ApplicationId Poll(*accounts.AuthData) ([]*PushMessageBatch, error) } // AuthTokens is a map with tokens the plugins are to use to make requests. type AuthTokens map[string]interface{} // ApplicationId represents the application id to direct posts to. // e.g.: com.ubuntu.diaspora_diaspora or com.ubuntu.diaspora_diaspora_1.0 type ApplicationId string // NewStandardPushMessage creates a base Notification with common // components (members) setup. func NewStandardPushMessage(summary, body, action, icon string, epoch int64) *PushMessage { pm := &PushMessage{ Notification: Notification{ Card: &Card{ Summary: summary, Body: body, Actions: []string{action}, Icon: icon, Timestamp: epoch, Popup: true, Persist: true, }, Sound: DefaultSound(), Vibrate: true, Tag: cmdName, }, } return pm } // PushMessageBatch represents a logical grouping of PushMessages that // have a limit on the number of their notifications that want to be // presented to the user at the same time, and a way to handle the // overflow. All Notifications that are part of a Batch share the same // tag (Tag). ${Tag}-overflow is the overflow notification tag. // // TODO: support notifications sharing just the prefix (so the app can // tell them apart by tag). type PushMessageBatch struct { Messages []*PushMessage Limit int OverflowHandler func([]*PushMessage) *PushMessage Tag string } // PushMessage represents a data structure to be sent over to the // Post Office. It consists of a Notification and a Message. type PushMessage struct { // Message represents a JSON object that is passed as-is to the // application Message string `json:"message,omitempty"` // Notification (optional) describes the user-facing notifications // triggered by this push message. Notification Notification `json:"notification,omitempty"` } // Notification (optional) describes the user-facing notifications // triggered by this push message. type Notification struct { // Sound (optional) is the path to a sound file which can or // cannot be played depending on user preferences. Sound string `json:"sound,omitempty"` // Card represents a specific bubble to give to the user Card *Card `json:"card,omitempty"` // Vibrate is the haptic feedback part of a notification. Vibrate bool `json:"vibrate,omitempty"` // EmblemCounter represents and application counter hint // related to the notification. EmblemCounter *EmblemCounter `json:"emblem-counter,omitempty"` // Tag represents a tag to identify persistent notifications Tag string `json:"tag,omitempty"` } // Card is part of a notification and represents the user visible hints for // a specific notification. type Card struct { // Summary is a required title. The card will not be presented if this is missing. Summary string `json:"summary"` // Body is the longer text. Body string `json:"body,omitempty"` // Whether to show a bubble. Users can disable this, and can easily miss // them, so don’t rely on it exclusively. Popup bool `json:"popup,omitempty"` // Actions provides actions for the bubble's snap decissions. Actions []string `json:"actions,omitempty"` // Icon is a path to an icon to display with the notification bubble. Icon string `json:"icon,omitempty"` // Whether to show in notification centre. Persist bool `json:"persist,omitempty"` // Seconds since the unix epoch, useful for persistent cards. Timestamp int64 `json:"Timestamp,omitempty"` } // EmblemCounter is part of a notification and represents the application visual // hints related to a notification. type EmblemCounter struct { // Count is a number to be displayed over the application’s icon in the // launcher. Count uint `json:"count"` // Visible determines if the counter is visible or not. Visible bool `json:"visible"` } // The constanst defined here determine the polling aggressivenes with the following criteria // MAXIMUM: calls, health warning // HIGH: SMS, chat message, new email // DEFAULT: social media updates // LOW: software updates, junk email const ( PRIORITY_MAXIMUM = 0 PRIORITY_HIGH PRIORITY_DEFAULT PRIORITY_LOW ) const ( PLUGIN_EMAIL = 0 PLUGIN_SOCIAL ) // ErrTokenExpired is the error returned by a plugin to indicate that // the web service reported that the authentication token has expired. var ErrTokenExpired = errors.New("Token expired") var cmdName string var XdgDataFind = xdg.Data.Find var XdgDataEnsure = xdg.Data.Ensure // Persist stores the plugins data in a common location to a json file // from which it can recover later func Persist(pluginName string, accountId uint, data interface{}) (err error) { var p string defer func() { if err != nil && p != "" { os.Remove(p) } }() p, err = XdgDataEnsure(filepath.Join(cmdName, fmt.Sprintf("%s-%d.json", pluginName, accountId))) if err != nil { return err } file, err := os.Create(p) if err != nil { return err } defer file.Close() w := bufio.NewWriter(file) defer w.Flush() jsonWriter := json.NewEncoder(w) if err := jsonWriter.Encode(data); err != nil { return err } return nil } // FromPersist restores the plugins data from a common location which // was stored in a json file func FromPersist(pluginName string, accountId uint, data interface{}) (err error) { if reflect.ValueOf(data).Kind() != reflect.Ptr { return errors.New("decode target is not a pointer") } var p string defer func() { if err != nil { if p != "" { os.Remove(p) } } }() p, err = XdgDataFind(filepath.Join(cmdName, fmt.Sprintf("%s-%d.json", pluginName, accountId))) if err != nil { return err } file, err := os.Open(p) if err != nil { return err } defer file.Close() jsonReader := json.NewDecoder(file) if err := jsonReader.Decode(&data); err != nil { return err } return nil } // DefaultSound returns the path to the default sound for a Notification func DefaultSound() string { // path is searched within XDG_DATA_DIRS return "sounds/ubuntu/notifications/Blip.ogg" } account-polld-0.1+16.04.20160308.1/pollbus/0000755000015600001650000000000012667557117020322 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/pollbus/bus.go0000644000015600001650000000432212667556700021440 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package pollbus import ( "fmt" "runtime" "log" "launchpad.net/go-dbus/v1" ) const ( busInterface = "com.ubuntu.AccountPolld" busPath = "/com/ubuntu/AccountPolld" busName = "com.ubuntu.AccountPolld" ) type PollBus struct { conn *dbus.Connection msgChan chan *dbus.Message PollChan chan bool } func New(conn *dbus.Connection) *PollBus { p := &PollBus{ conn: conn, msgChan: make(chan *dbus.Message), PollChan: make(chan bool), } runtime.SetFinalizer(p, clean) return p } func clean(p *PollBus) { p.conn.UnregisterObjectPath(busPath) close(p.msgChan) close(p.PollChan) } func (p *PollBus) Init() error { name := p.conn.RequestName(busName, dbus.NameFlagDoNotQueue) err := <-name.C if err != nil { return fmt.Errorf("bus name could not be take: %s", err) } go p.watchMethodCalls() p.conn.RegisterObjectPath(busPath, p.msgChan) return nil } func (p *PollBus) SignalDone() error { signal := dbus.NewSignalMessage(busPath, busInterface, "Done") if err := p.conn.Send(signal); err != nil { return err } return nil } func (p *PollBus) watchMethodCalls() { for msg := range p.msgChan { var reply *dbus.Message switch { case msg.Interface == busInterface && msg.Member == "Poll": log.Println("Received Poll()") p.PollChan <- true reply = dbus.NewMethodReturnMessage(msg) default: log.Println("Received unkown method call on", msg.Interface, msg.Member) reply = dbus.NewErrorMessage(msg, "org.freedesktop.DBus.Error.UnknownMethod", "Unknown method") } if err := p.conn.Send(reply); err != nil { log.Println("Could not send reply:", err) } } } account-polld-0.1+16.04.20160308.1/po/0000755000015600001650000000000012667557117017260 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/po/pl.po0000644000015600001650000000626312667556700020237 0ustar pbuserpbgroup00000000000000# Polish translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-07-25 17:33+0000\n" "Last-Translator: GTriderXC \n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Dostępnych jest więcej nieprzeczytanych wiadomości" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Ilość nieprzeczytanych wiadomości: %d" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Dostępne więcej wpisów" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Od %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Dostępnych jest więcej wiadomości" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Więcej wiadomości" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Więcej powiadomień" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Powiadomienia" #~ msgid "Receive notifications for this account" #~ msgstr "Otrzymuj powiadomienia dla tego konta" account-polld-0.1+16.04.20160308.1/po/bs.po0000644000015600001650000000651212667556700020225 0ustar pbuserpbgroup00000000000000# Bosnian translation for account-polld # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-03-24 20:06+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Bosnian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Više nepročitanih email-ova je dostupno" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Više višestrukih napomena" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Od %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Direktne višestruke poruke su dostupne" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Više višestrukih poruka" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Više višestrukih obavijesti" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Obavještenja" #~ msgid "Account Polling" #~ msgstr "Biranje računa" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Imate tačno %d nepročitanih poruka" #~ msgid "Receive notifications for this account" #~ msgstr "Dobijaj obavještenja za ovaj račun" account-polld-0.1+16.04.20160308.1/po/az.po0000644000015600001650000000566712667556700020245 0ustar pbuserpbgroup00000000000000# Azerbaijani translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-08-31 16:15+0000\n" "Last-Translator: Nicat Məmmədov \n" "Language-Team: Azerbaijani \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr "" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Göndәrәn: %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Çoxlu mesaj göndәr" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Bildirişlər" account-polld-0.1+16.04.20160308.1/po/gl.po0000644000015600001650000000655412667556700020231 0ustar pbuserpbgroup00000000000000# Galician translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-15 13:15+0000\n" "Last-Translator: Marcos Lans \n" "Language-Team: Galician \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Máis correos sen ler dispoñíbeis" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Ten aprox. %d mensaxes máis sen ler" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Varias mencións máis" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Hai varias mensaxes directas dispoñíbeis" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Varias mensaxes máis" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Varias notificacións máis" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificacións" #~ msgid "Receive notifications for this account" #~ msgstr "Recibir notificacións desta conta" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Ten aproximadamente %d mensaxes adicionais sen ler" #~ msgid "Account Polling" #~ msgstr "Consulta de contas" account-polld-0.1+16.04.20160308.1/po/nl.po0000644000015600001650000000656512667556700020242 0ustar pbuserpbgroup00000000000000# Dutch translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-16 07:47+0000\n" "Last-Translator: rob \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "U heeft meerdere ongelezen e-mailberichten" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "U heeft nog %d ongelezen e-mailberichten" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "U heeft meerdere vermeldingen" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Van %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "U heeft meerdere privéberichten" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "U heeft meerdere berichten" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "U heeft meerdere meldingen" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificaties" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "U heeft ongeveer %d ongelezen e-mailberichten" #~ msgid "Receive notifications for this account" #~ msgstr "Notificaties ontvangen voor dit account" #~ msgid "Account Polling" #~ msgstr "Accountnotificaties" account-polld-0.1+16.04.20160308.1/po/ca.po0000644000015600001650000000657012667556700020210 0ustar pbuserpbgroup00000000000000# Catalan translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-09-07 04:04+0000\n" "Last-Translator: David Planella \n" "Language-Team: Catalan \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Hi ha més correus per llegir disponibles" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Teniu uns altres %d missatges sense llegir" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Diverses mencions" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Diversos missatges directes" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Més notificacions múltiples" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Més notifications" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificacions" #~ msgid "Receive notifications for this account" #~ msgstr "Vull rebre notificacions per a aquest compte" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Teniu uns altres %d missatges sense llegir" #~ msgid "Account Polling" #~ msgstr "Consulta de comptes" account-polld-0.1+16.04.20160308.1/po/zh_TW.po0000644000015600001650000000645412667556700020661 0ustar pbuserpbgroup00000000000000# Chinese (Traditional) translation for account-polld # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-03-01 09:48+0000\n" "Last-Translator: Cheng-Chia Tseng \n" "Language-Team: Chinese (Traditional) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr "、%s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "有更多則未讀電子郵件" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s。@%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "更多條提及通知" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "來自 %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "有更多直接訊息" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "更多則訊息" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "更多項通知" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "通知" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "您大概有 %d 則其他未讀訊息" #~ msgid "Receive notifications for this account" #~ msgstr "接收此帳號的通知" #~ msgid "Account Polling" #~ msgstr "帳號 Polling" account-polld-0.1+16.04.20160308.1/po/ca@valencia.po0000644000015600001650000000651412667556700022011 0ustar pbuserpbgroup00000000000000# Catalan translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-10-17 14:24+0000\n" "Last-Translator: David Planella \n" "Language-Team: Catalan \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Hi ha més correus per llegir disponibles" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Diverses mencions" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Diversos missatges directes" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Més notificacions múltiples" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Més notifications" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificacions" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Teniu uns altres %d missatges sense llegir" #~ msgid "Account Polling" #~ msgstr "Consulta de comptes" #~ msgid "Receive notifications for this account" #~ msgstr "Vull rebre notificacions per a este compte" account-polld-0.1+16.04.20160308.1/po/nb.po0000644000015600001650000000653012667556700020220 0ustar pbuserpbgroup00000000000000# Norwegian Bokmal translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-15 08:11+0000\n" "Last-Translator: Åka Sikrom \n" "Language-Team: Norwegian Bokmal \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Flere uleste e-postmeldinger tilgjengelig" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Du har cirka %d andre uleste meldinger" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s (@%s)" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Nevnt i flere innlegg" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Fra %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Flere direktemeldinger er tilgjengelig" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Flere meldinger" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Flere varslinger" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Varslinger" #~ msgid "Account Polling" #~ msgstr "Kontoprøving" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Du har cirka %d andre uleste meldinger" #~ msgid "Receive notifications for this account" #~ msgstr "Få varslinger om denne kontoen" account-polld-0.1+16.04.20160308.1/po/cs.po0000644000015600001650000000612312667556700020224 0ustar pbuserpbgroup00000000000000# Czech translation for account-polld # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-05-06 19:22+0000\n" "Last-Translator: Texis \n" "Language-Team: Czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Přijato několik nových emailů" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Máte kolem %d nepřečtených zpráv" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Přijato několik nových zmínek" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Od %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Přijato několik nových zpráv" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Přijato několik nových zpráv" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Přijato několik nových oznámení" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Oznámení" account-polld-0.1+16.04.20160308.1/po/fa.po0000644000015600001650000000703512667556700020210 0ustar pbuserpbgroup00000000000000# Persian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-21 22:23+0000\n" "Last-Translator: Danial Behzadi \n" "Language-Team: Persian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr "، %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "ای‌میل‌های ناخوانده‌ی بیش‌تری موجودند" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "شما حدود %d پیام نخوانده دارید" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "‫%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "چند اشاره‌ی بیش‌تر" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "از %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "چند پیام خصوصی موجود است" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "چند پیام دیگر" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "چند اطّلاعیه‌ی دیگر" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "آگهی‌ها" #~ msgid "Receive notifications for this account" #~ msgstr "دریافت آگهی‌ها برای این حساب کاربری" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "شما حدود %d پیام ناخوانده‌ی جدید دارید" #~ msgid "Account Polling" #~ msgstr "سرکشی به حساب کاربری" account-polld-0.1+16.04.20160308.1/po/pt.po0000644000015600001650000000657412667556700020254 0ustar pbuserpbgroup00000000000000# Portuguese translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-07-30 10:02+0000\n" "Last-Translator: Ivo Xavier \n" "Language-Team: Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Mais emails disponíveis para ler" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Tem aproximadamente %d mensagens para ler" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Várias menções múltiplas" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Várias mensagens diretas disponíveis" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Mais mensagens" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Mais notificações" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificações" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Tem aproximadamente %d mensagens não lidas adicionais" #~ msgid "Receive notifications for this account" #~ msgstr "Receber notificações para esta conta" #~ msgid "Account Polling" #~ msgstr "Polling de conta" account-polld-0.1+16.04.20160308.1/po/en_GB.po0000644000015600001650000000661012667556700020572 0ustar pbuserpbgroup00000000000000# English (United Kingdom) translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-03-25 15:07+0000\n" "Last-Translator: James Hudson \n" "Language-Team: English (United Kingdom) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "More unread emails available" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "You have about %d more unread messages" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Multiple more mentions" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "From %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Multiple direct messages available" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Multiple more messages" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Multiple more notifications" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notifications" #~ msgid "Receive notifications for this account" #~ msgstr "Receive notifications for this account" #~ msgid "Account Polling" #~ msgstr "Account Polling" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "You have approximately %d additional unread messages" account-polld-0.1+16.04.20160308.1/po/pt_BR.po0000644000015600001650000000660112667556700020626 0ustar pbuserpbgroup00000000000000# Brazilian Portuguese translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-27 13:28+0000\n" "Last-Translator: Tiago Hillebrandt \n" "Language-Team: Brazilian Portuguese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Mais e-mails não lidos" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Você tem cerca de %d mensagens não lidas" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Varias menções" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Varias mensagens diretas" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Mais mensagens" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Diversas notificações" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificações" #~ msgid "Receive notifications for this account" #~ msgstr "Receber notificações para esta conta" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Você tem um valor aproximado de %d mensagens não lidas" #~ msgid "Account Polling" #~ msgstr "Conta de votação" account-polld-0.1+16.04.20160308.1/po/sv.po0000644000015600001650000000650612667556700020254 0ustar pbuserpbgroup00000000000000# Swedish translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-17 17:16+0000\n" "Last-Translator: Josef Andersson \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Fler olästa meddelanden tillgängliga" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Du har %d olästa meddelanden" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Fler omnämnanden" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Från %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Fler omnämnanden tillgängliga" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Fler meddelanden" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Fler aviseringar" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Aviseringar" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Du har ytterligare cirka %d olästa meddelanden" #~ msgid "Account Polling" #~ msgstr "Kontoavsökning" #~ msgid "Receive notifications for this account" #~ msgstr "Ta emot aviseringar för detta konto" account-polld-0.1+16.04.20160308.1/po/lv.po0000644000015600001650000000563312667556700020245 0ustar pbuserpbgroup00000000000000# Latvian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-08-15 16:19+0000\n" "Last-Translator: Jānis Marks Gailis \n" "Language-Team: Latvian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "No %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Paziņojumi" account-polld-0.1+16.04.20160308.1/po/ko.po0000644000015600001650000000665712667556700020244 0ustar pbuserpbgroup00000000000000# Korean translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-08-19 00:58+0000\n" "Last-Translator: MinSik CHO \n" "Language-Team: Korean \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "확인하지 않은 이메일이 있습니다" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "약 %d개의 메시지를 확인하지 않았습니다." #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "확인하지 않은 여러 멘션들이 있습니다" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "보낸 사람: %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "확인하지 않은 여러 메세지가 있습니다" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "확인하지 않은 페이스북 알림이 있습니다" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "알림" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "확인하지 않은 %d개의 메세지가 있습니다" #~ msgid "Account Polling" #~ msgstr "계정 투표" #~ msgid "Receive notifications for this account" #~ msgstr "이 계정의 알림 받기" account-polld-0.1+16.04.20160308.1/po/hu.po0000644000015600001650000000662312667556700020240 0ustar pbuserpbgroup00000000000000# Hungarian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-15 08:49+0000\n" "Last-Translator: Richard Somlói \n" "Language-Team: Hungarian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Több olvasatlan e-mail érhető el" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Körülbelül további %d olvasatlan üzenete van" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Több említés is történt" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Tőle: %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Több közvetlen üzenet érhető el" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Több üzenete is érkezett" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Több értesítés is érkezett" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Értesítések" #~ msgid "Account Polling" #~ msgstr "Fiók lekérdezés" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "További %d olvasatlan üzenete van" #~ msgid "Receive notifications for this account" #~ msgstr "Értesítések fogadása ezzel a fiókkal" account-polld-0.1+16.04.20160308.1/po/br.po0000644000015600001650000000617212667556700020226 0ustar pbuserpbgroup00000000000000# Breton translation for account-polld # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-06-05 06:23+0000\n" "Last-Translator: Fohanno Thierry \n" "Language-Team: Breton \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Bez' ez eus posteloù all ha n'int ket bet lennet" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Bez' ho peus war-dro %d a gemennadennoù n'int ket bet lennet" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Meur a veneg zo da gaout" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Digant %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Meur a gemennadenn brevez zo da gaout" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Meur a gemennadenn all" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Meur a gemenn all zo da gaout" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Kemennoù" account-polld-0.1+16.04.20160308.1/po/sl.po0000644000015600001650000000654312667556700020243 0ustar pbuserpbgroup00000000000000# Slovenian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-16 12:05+0000\n" "Last-Translator: Sasa Batistic \n" "Language-Team: Slovenian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Na voljo je več neprebrane e-pošte" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Imate še več kot %d neprebranih sporočil." #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Večje število omemb" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Od %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Na voljo je večje število neposrednih sporočil" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Več sporočil" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Več obvestil" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Obvestila" #~ msgid "Receive notifications for this account" #~ msgstr "Prejmi obvestila za ta račun" #~ msgid "Account Polling" #~ msgstr "Izpraševanje računa" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Imate približno %d dodatnih neprebranih sporočil" account-polld-0.1+16.04.20160308.1/po/it.po0000644000015600001650000000656112667556700020241 0ustar pbuserpbgroup00000000000000# Italian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-15 16:41+0000\n" "Last-Translator: Claudio Arseni \n" "Language-Team: Italian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Altre email non lette disponibili" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Ci sono circa %d ulteriori messaggi non letti" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Molteplici menzioni" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Da %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Molteplici messaggi diretti dipsonibili" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Molteplici messaggi" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Molteplici notifiche" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notifiche" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Sono presenti circa %d ulteriori email da leggere" #~ msgid "Receive notifications for this account" #~ msgstr "Ricevere notifiche per questo account" #~ msgid "Account Polling" #~ msgstr "Gestione account" account-polld-0.1+16.04.20160308.1/po/gd.po0000644000015600001650000000670112667556700020213 0ustar pbuserpbgroup00000000000000# Gaelic; Scottish translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # GunChleoc , 2014. msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-09-03 13:18+0000\n" "Last-Translator: GunChleoc \n" "Language-Team: Fòram na Gàidhlig\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" "Language: gd\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Tha barrachd puist-d ann nach deach an leughadh" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Tha mu %d teachdaireachd(an) eile gun leughadh agad" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Barrachd iomraidhean" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "O %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Tha teachdaireachdan dìreach ri làimh" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Barrachd theachdaireachdan" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Tha iomadh brath eile ann" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Brathan" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Tha mu thuaiream %d teachdaireachd eile gun leughadh agad" #~ msgid "Receive notifications for this account" #~ msgstr "Faigh brathan on chunntas seo" #~ msgid "Account Polling" #~ msgstr "Polling chunntasan" account-polld-0.1+16.04.20160308.1/po/account-polld.pot0000644000015600001650000000532312667556700022550 0ustar pbuserpbgroup00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Canonical Ltd. # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr "" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "" account-polld-0.1+16.04.20160308.1/po/km.po0000644000015600001650000000722512667556700020232 0ustar pbuserpbgroup00000000000000# Khmer translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-08-20 03:55+0000\n" "Last-Translator: Sophea Sok \n" "Language-Team: Khmer \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "មាន​អ៊ីមែល​មិន​បាន​អាន​ច្រើន​ទៀត" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "ការ​ពិភាក្សា​ច្រើន​ទៀត" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "ពី %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "មាន​សារ​ផ្ទាល់​ច្រើន" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "ការ​ជូនដំណឹង​ច្រើន​ទៀត" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "ការ​ជូនដំណឹង" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "អ្នក​មាន​សារ​ដែល​មិន​បាន​អាន​ប្រហែល %d" #~ msgid "Account Polling" #~ msgstr "ការ​ស្ទង់​មតិ​គណនី" #~ msgid "Receive notifications for this account" #~ msgstr "ទទួល​ការ​ជូនដំណឹង​សម្រាប់​គណនី​នេះ" account-polld-0.1+16.04.20160308.1/po/el.po0000644000015600001650000000737312667556700020227 0ustar pbuserpbgroup00000000000000# Greek translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-06-10 06:46+0000\n" "Last-Translator: Simos Xenitellis \n" "Language-Team: Greek \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Περισσότερα διαθέσιμα αδιάβαστα μηνύματα ηλεκτρονικού ταχυδρομείου" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Έχετε ακόμα γύρω στα %d μη αναγνωσμένα μηνύματα" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Περισσότερες πολλαπλές αναφορές" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Από %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Πολλαπλά άμεσα μηνύματα διαθέσιμα" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Περισσότερα πολλαπλά μηνύματα" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Περισσότερες πολλαπλές ειδοποιήσεις" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Ειδοποιήσεις" #~ msgid "Account Polling" #~ msgstr "Ψηφοφορία Λογαριασμού" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Έχετε κατά προσέγγιση %d επιπλέον αδιάβαστα μηνύματα" #~ msgid "Receive notifications for this account" #~ msgstr "Λήψη ειδοποιήσεων για αυτό το λογαριασμό" account-polld-0.1+16.04.20160308.1/po/sr.po0000644000015600001650000000713512667556700020247 0ustar pbuserpbgroup00000000000000# Serbian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-10-26 21:49+0000\n" "Last-Translator: Данило Шеган \n" "Language-Team: Serbian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Доступно је још непрочитаних е-писама" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Имате још око %d непрочитаних порука" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Вишеструко још помињања" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Од %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Доступне су вишеструке директне поруке" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Вишеструко још порука" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Вишеструко још обавештења" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Обавештења" #~ msgid "Account Polling" #~ msgstr "Запиткивање налога" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Имате приближно још %d непрочитаних порука" #~ msgid "Receive notifications for this account" #~ msgstr "Примај обавештења за овај налог" account-polld-0.1+16.04.20160308.1/po/da.po0000644000015600001650000000571312667556700020207 0ustar pbuserpbgroup00000000000000# Danish translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-08-07 14:43+0000\n" "Last-Translator: Ask Hjorth Larsen \n" "Language-Team: Danish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Flere yderligere nævnelser" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Fra %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Flere direkte meddelelser tilgængelige" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "" account-polld-0.1+16.04.20160308.1/po/eu.po0000644000015600001650000000655512667556700020241 0ustar pbuserpbgroup00000000000000# Basque translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-20 23:28+0000\n" "Last-Translator: Ibai Oihanguren Sala \n" "Language-Team: Basque \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Irakurri gabeko mezu gehiago" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Irakurri gabeko beste %d mezu inguru dituzu" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Hainbat aipamen gehiago" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Nork: %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Hainbat zuzeneko mezu irakurgai" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Hainbat mezu gehiago" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Hainbat jakinarazpen gehiago" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Jakinarazpenak" #~ msgid "Receive notifications for this account" #~ msgstr "Jaso kontu honentzako jakinarazpenak" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Batez beste irakurri gabeko %d mezu gehiago dituzu" #~ msgid "Account Polling" #~ msgstr "Kontuaren zundaketa" account-polld-0.1+16.04.20160308.1/po/hr.po0000644000015600001650000000652112667556700020232 0ustar pbuserpbgroup00000000000000# Croatian translation for account-polld # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-01 13:25+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Croatian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Više izravnih poruka e-pošte dostupno" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Imate još oko %d nepročitanih poruka" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Još više napomena" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Od %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Više izravnih poruka dostupno" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Još više poruka" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Još više obavijesti" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Obavijesti" #~ msgid "Account Polling" #~ msgstr "Pozivanje računa" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Imate približno %d dodatnih nepročitanih poruka" #~ msgid "Receive notifications for this account" #~ msgstr "Primaj poruke za ovaj račun" account-polld-0.1+16.04.20160308.1/po/is.po0000644000015600001650000000654012667556700020235 0ustar pbuserpbgroup00000000000000# Icelandic translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-09-15 08:04+0000\n" "Last-Translator: Sveinn í Felli \n" "Language-Team: Icelandic \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Fleiri ólesnir tölvupóstar tiltækir" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Fleiri hafa minnst á þetta" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Frá %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Mörg bein skilaboð tiltæk" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Mörg fleiri skilaboð" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Fleiri tilkynningar" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Tilkynningar" #~ msgid "Account Polling" #~ msgstr "Aðgangsvöktun" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Til viðbótar eru um það bil %d ólesnir tölvupóstar" #~ msgid "Receive notifications for this account" #~ msgstr "Fá tilkynningar varðandi þennan aðgangsreikning" account-polld-0.1+16.04.20160308.1/po/en_AU.po0000644000015600001650000000662112667556700020611 0ustar pbuserpbgroup00000000000000# English (Australia) translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-18 02:11+0000\n" "Last-Translator: Jared Norris \n" "Language-Team: English (Australia) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "More unread emails available" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "You have about %d more unread messages" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Multiple more mentions" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "From %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Multiple direct messages available" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Multiple more messages" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Multiple more notifications" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notifications" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "You have an approximate of %d additional unread messages" #~ msgid "Account Polling" #~ msgstr "Account Polling" #~ msgid "Receive notifications for this account" #~ msgstr "Receive notifications for this account" account-polld-0.1+16.04.20160308.1/po/uk.po0000644000015600001650000000723612667556700020244 0ustar pbuserpbgroup00000000000000# Ukrainian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-08-30 11:41+0000\n" "Last-Translator: Yuri Chornoivan \n" "Language-Team: Ukrainian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Є інші непрочитані повідомлення" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "У вас ще приблизно %d непрочитаних повідомлень" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Ще декілька згадок" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Від %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Доступно декілька безпосередніх повідомлень" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Ще декілька повідомлень" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Ще декілька сповіщень" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Сповіщення" #~ msgid "Account Polling" #~ msgstr "Опитування запису" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "У вас ще приблизно %d інших непрочитаних повідомлень" #~ msgid "Receive notifications for this account" #~ msgstr "Отримувати сповіщення для цього облікового запису" account-polld-0.1+16.04.20160308.1/po/fi.po0000644000015600001650000000660212667556700020217 0ustar pbuserpbgroup00000000000000# Finnish translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-16 07:03+0000\n" "Last-Translator: Jiri Grönroos \n" "Language-Team: Finnish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Lisää lukemattomia sähköposteja saatavilla" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Sinulla on noin %d lukematonta viestiä lisää" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Useita lisämainintoja" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Lähettäjä %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Useita suoraviestejä saatavilla" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Useita viestejä lisää" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Useita ilmoituksia lisää" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Ilmoitukset" #~ msgid "Receive notifications for this account" #~ msgstr "Vastaanota ilmoituksia tällä tilillä" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Sinulla on noin %d lukematonta viestiä" #~ msgid "Account Polling" #~ msgstr "Käyttäjätilien kysely" account-polld-0.1+16.04.20160308.1/po/ru.po0000644000015600001650000000707312667556700020252 0ustar pbuserpbgroup00000000000000# Russian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-09-02 08:15+0000\n" "Last-Translator: ☠Jay ZDLin☠ \n" "Language-Team: Russian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Имеются ещё непрочитанные письма" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "У вас ещё около %d непрочитанных сообщений" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Ещё упоминания" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "От %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Имеются личные сообщения" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Ещё сообщения" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Ещё уведомления" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Уведомления" #~ msgid "Account Polling" #~ msgstr "Проверка учётной записи" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Имеется ещё порядка %d непрочитанных сообщений" #~ msgid "Receive notifications for this account" #~ msgstr "Получать уведомления для данной учётной записи" account-polld-0.1+16.04.20160308.1/po/ro.po0000644000015600001650000000664312667556700020246 0ustar pbuserpbgroup00000000000000# Romanian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-18 18:44+0000\n" "Last-Translator: Meriuță Cornel \n" "Language-Team: Romanian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Există mai multe mesaje e-mail necitite" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Aveți aproximativ mai mult de %d mesaje necitite" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Mai multe menționări multiple" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De la %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Sunt disponibile mesaje directe multiple" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Mai multe mesaje multiple" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Mai multe notificări multiple" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificări" #~ msgid "Account Polling" #~ msgstr "Cont votare" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Aveți aproximativ %d mesaje suplimentare necitite" #~ msgid "Receive notifications for this account" #~ msgstr "Pentru acest cont se primesc notificări" account-polld-0.1+16.04.20160308.1/po/he.po0000644000015600001650000000661312667556700020217 0ustar pbuserpbgroup00000000000000# Hebrew translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-09-04 06:45+0000\n" "Last-Translator: Yaron \n" "Language-Team: Hebrew \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "אין הודעות דוא״ל שלא נקראו" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "מספר אזכורים נוספים" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "מאת %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "מספר הודעות ישירות זמינות" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "מספר הודעות נוספות" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "עוד מספר התרעות" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "התרעות" #~ msgid "Receive notifications for this account" #~ msgstr "קבלת התרעות לחשבון זה" #~ msgid "Account Polling" #~ msgstr "אחזור מהחשבונות" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "יש לך בערך %d הודעות שלא נקראו" account-polld-0.1+16.04.20160308.1/po/am.po0000644000015600001650000000711312667556700020214 0ustar pbuserpbgroup00000000000000# Amharic translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-15 22:53+0000\n" "Last-Translator: samson \n" "Language-Team: Amharic \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "ተጨማሪ ያልተነበቡ ኢሜይሎች ዝግጁ ናቸው" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "እርስዎ በግምት %d ያልተነበቡ መልእክቶች አለዎት" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "በርካታ ተጨማሪዎች አሉ" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "ከ %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "በርካታ ቀጥተኛ መልእክቶች ዝግጁ ናቸው" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "በርካታ ተጨማሪ መልእክቶች" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "ተጨማሪ በርካታ ማስታወቂያዎች" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "ማስታወቂያዎች" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "በግምት %d ተጨማሪ ያልተነበቡ መልእክቶች" #~ msgid "Account Polling" #~ msgstr "የ መግለጫ ድምፅ መስጫ" #~ msgid "Receive notifications for this account" #~ msgstr "ለዚህ መግለጫ ማስታወቂያዎች መቀበያ" account-polld-0.1+16.04.20160308.1/po/es.po0000644000015600001650000000651512667556700020233 0ustar pbuserpbgroup00000000000000# Spanish translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-14 22:58+0000\n" "Last-Translator: Adolfo Jayme \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Más mensajes sin leer" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Hay aproximadamente %d mensajes sin leer" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Varias menciones" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Varios mensajes directos" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Muchos más mensajes" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Muchas más notificaciones" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificaciones" #~ msgid "Receive notifications for this account" #~ msgstr "Recibir notificaciones de esta cuenta" #~ msgid "Account Polling" #~ msgstr "Sondeo de cuentas" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Hay aproximadamente %d mensajes sin leer" account-polld-0.1+16.04.20160308.1/po/ug.po0000644000015600001650000000705412667556700020236 0ustar pbuserpbgroup00000000000000# Uyghur translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-09-23 02:23+0000\n" "Last-Translator: Gheyret T.Kenji \n" "Language-Team: Uyghur \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr "، %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "كۆپلىگەن ئوقۇلمىغان ئېلخەتلەر بار" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "كۆپلىگەن نەقىللەر بار" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "ئەۋەتكۈچى %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "كۆپلىگەن بىۋاسىتە ئۇچۇرلار بار" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "كۆپلىگەن ئۇچۇرلار بار" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "كۆپلىگەن ئۇقتۇرۇشلار بار" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "ئۇقتۇرۇشلار" #~ msgid "Receive notifications for this account" #~ msgstr "بۇ ھېساباتتىن كەلگەن ئۇقتۇرۇشلارنى قوبۇل قىلسۇن" #~ msgid "Account Polling" #~ msgstr "ھېسابات ئۇقتۇرۇشى" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "تەخمىنەن يەنە %d دانە ئوقۇلمىغان ئېلخەتلەر بار" account-polld-0.1+16.04.20160308.1/po/fr.po0000644000015600001650000000664712667556700020241 0ustar pbuserpbgroup00000000000000# French translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-18 10:17+0000\n" "Last-Translator: Anne \n" "Language-Team: French \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Plusieurs courriels non lus disponibles" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Vous avez environ %d messages non lus supplémentaires" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Plusieurs mentions disponibles" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Plusieurs messages privés disponibles" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Plusieurs autres messages" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Plusieurs notifications disponibles" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notifications" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Vous avez approximativement %d nouveaux messages non lus" #~ msgid "Receive notifications for this account" #~ msgstr "Recevoir des notifications pour ce compte" #~ msgid "Account Polling" #~ msgstr "Interrogation du compte" account-polld-0.1+16.04.20160308.1/po/vi.po0000644000015600001650000000554412667556700020243 0ustar pbuserpbgroup00000000000000# Vietnamese translation for account-polld # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-02 19:02+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Vietnamese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr "" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "" account-polld-0.1+16.04.20160308.1/po/ja.po0000644000015600001650000000661512667556700020217 0ustar pbuserpbgroup00000000000000# Japanese translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2014-09-18 06:29+0000\n" "Last-Translator: Kentaro Kazuhama \n" "Language-Team: Japanese \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr "、%s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "さらに未読のメールがあります" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "複数のメッセージがあります" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "%sより" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "複数のダイレクトメッセージがあります" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "複数のメッセージ" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "複数の通知があります" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "通知" #~ msgid "Account Polling" #~ msgstr "アカウント通知" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "さらに%d件の未読メッセージがあります" #~ msgid "Receive notifications for this account" #~ msgstr "このアカウントからの通知を受信します" account-polld-0.1+16.04.20160308.1/po/de.po0000644000015600001650000000664312667556700020216 0ustar pbuserpbgroup00000000000000# German translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-15 23:10+0000\n" "Last-Translator: Niklas Wenzel \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Weitere ungelesene E-Mails verfügbar" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Sie haben ungefähr %d ungelesene Nachrichten" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Mehrere weitere Erwähnungen" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Von %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Mehrere Direktnachrichten verfügbar" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Mehrere zusätzliche Nachrichten" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Mehrere weitere Benachrichtigungen" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Benachrichtigungen" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Sie haben etwa %d weitere ungelesene Nachrichten" #~ msgid "Receive notifications for this account" #~ msgstr "Benachrichtigungen für dieses Konto erhalten" #~ msgid "Account Polling" #~ msgstr "Kontoabfragen" account-polld-0.1+16.04.20160308.1/po/zh_CN.po0000644000015600001650000000605112667556700020620 0ustar pbuserpbgroup00000000000000# Chinese (Simplified) translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-06-26 04:12+0000\n" "Last-Translator: Ian Li \n" "Language-Team: Chinese (Simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ",%s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "还有更多未读邮件" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "您大约还有 %d 条未读消息" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "有多条推文提到你" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "来自 %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "有多条推特的私信" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "还有更多消息" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "还有更多通知" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "通知" account-polld-0.1+16.04.20160308.1/po/aa.po0000644000015600001650000000612212667556700020177 0ustar pbuserpbgroup00000000000000# Afar translation for account-polld # Copyright (c) 2015 Rosetta Contributors and Canonical Ltd 2015 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2015. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-04-18 17:53+0000\n" "Last-Translator: Charif AYFARAH \n" "Language-Team: Afar \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Kalah kaadu kawse wayte imeelitte tan" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Kalah kaadu kawse wayte farmoomak %d lito" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Kalah kaadu mango cuso tan" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "Rubtam %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Massah tan mango farmooma tan" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Kalah kaadu mango farmooma tan" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Kalah kaadu mango mascassoosi tan" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Mascassoosi" account-polld-0.1+16.04.20160308.1/po/ast.po0000644000015600001650000000650212667556700020407 0ustar pbuserpbgroup00000000000000# Asturian translation for account-polld # Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 # This file is distributed under the same license as the account-polld package. # FIRST AUTHOR , 2014. # msgid "" msgstr "" "Project-Id-Version: account-polld\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2015-03-27 11:39+0000\n" "PO-Revision-Date: 2015-10-06 11:54+0000\n" "Last-Translator: Xuacu Saturio \n" "Language-Team: Asturian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2015-12-29 05:35+0000\n" "X-Generator: Launchpad (build 17865)\n" #. TRANSLATORS: the %s is an appended "from" corresponding to an specific email thread #: plugins/gmail/gmail.go:167 #, c-format msgid ", %s" msgstr ", %s" #. TRANSLATORS: the %s is the "from" header corresponding to a specific email #: plugins/gmail/gmail.go:170 #, c-format msgid "%s" msgstr "%s" #. TRANSLATORS: the first %s refers to the email "subject", the second %s refers "from" #: plugins/gmail/gmail.go:172 #, c-format msgid "" "%s\n" "%s" msgstr "" "%s\n" "%s" #. TRANSLATORS: This represents a notification summary about more unread emails #: plugins/gmail/gmail.go:190 msgid "More unread emails available" msgstr "Más mensaxes ensin lleer" #. TRANSLATORS: the first %d refers to approximate additional email message count #: plugins/gmail/gmail.go:194 #, c-format msgid "You have about %d more unread messages" msgstr "Tienes unos %d mensaxes más por lleer" #. TRANSLATORS: The first %s refers to the twitter user's Name, the second %s to the username. #: plugins/twitter/twitter.go:112 plugins/twitter/twitter.go:172 #, c-format msgid "%s. @%s" msgstr "%s. @%s" #. TRANSLATORS: This represents a notification summary about more twitter mentions available #: plugins/twitter/twitter.go:131 msgid "Multiple more mentions" msgstr "Delles menciones" #. TRANSLATORS: This represents a notification body with the comma separated twitter usernames #. TRANSLATORS: This represents a message body with the comma separated facebook usernames #. TRANSLATORS: This represents a notification body with the comma separated facebook usernames #: plugins/twitter/twitter.go:133 plugins/twitter/twitter.go:194 #: plugins/facebook/facebook.go:356 plugins/facebook/facebook.go:407 #, c-format msgid "From %s" msgstr "De %s" #. TRANSLATORS: This represents a notification summary about more twitter direct messages available #: plugins/twitter/twitter.go:192 msgid "Multiple direct messages available" msgstr "Dellos mensaxes direutos" #. TRANSLATORS: This represents a message summary about more facebook messages #: plugins/facebook/facebook.go:354 msgid "Multiple more messages" msgstr "Más mensaxes" #. TRANSLATORS: This represents a notification summary about more facebook notifications #: plugins/facebook/facebook.go:405 msgid "Multiple more notifications" msgstr "Más notificaciones" #: data/account-polld.desktop.tr.h:1 msgid "Notifications" msgstr "Notificaciones" #~ msgid "Account Polling" #~ msgstr "Sondéu de cuentes" #, c-format #~ msgid "You have an approximate of %d additional unread messages" #~ msgstr "Tienes alredor de %d correos ensin lleer" #~ msgid "Receive notifications for this account" #~ msgstr "Recibir notificaciones d'esta cuenta" account-polld-0.1+16.04.20160308.1/gettext/0000755000015600001650000000000012667557117020326 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/gettext/LICENSE0000644000015600001650000000211212667556700021324 0ustar pbuserpbgroup00000000000000Copyright (c) 2012-2013 José Carlos Nieto, http://xiam.menteslibres.org/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. account-polld-0.1+16.04.20160308.1/gettext/gettext.go0000644000015600001650000001347712667556700022352 0ustar pbuserpbgroup00000000000000/* Copyright (c) 2012 José Carlos Nieto, http://xiam.menteslibres.org/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ package gettext /* #include #include #include */ import "C" import ( "fmt" "strings" "unsafe" ) var ( // For all of the locale. LC_ALL = uint(C.LC_ALL) // For regular expression matching (it determines the meaning of range // expressions and equivalence classes) and string collation. LC_COLATE = uint(C.LC_ALL) // For regular expression matching, character classification, conversion, // case-sensitive comparison, and wide character functions. LC_CTYPE = uint(C.LC_CTYPE) // For localizable natural-language messages. LC_MESSAGES = uint(C.LC_MESSAGES) // For monetary formatting. LC_MONETARY = uint(C.LC_MONETARY) // For number formatting (such as the decimal point and the thousands // separator). LC_NUMERIC = uint(C.LC_NUMERIC) // For time and date formatting. LC_TIME = uint(C.LC_TIME) ) // Sets or queries the program's current locale. func SetLocale(category uint, locale string) string { clocale := C.CString(locale) res := C.GoString(C.setlocale(C.int(category), clocale)) C.free(unsafe.Pointer(clocale)) return res } // Sets directory containing message catalogs. func BindTextdomain(domainname string, dirname string) string { cdirname := C.CString(dirname) cdomainname := C.CString(domainname) res := C.GoString(C.bindtextdomain(cdomainname, cdirname)) C.free(unsafe.Pointer(cdirname)) C.free(unsafe.Pointer(cdomainname)) return res } // Sets the output codeset for message catalogs for domain domainname. func BindTextdomainCodeset(domainname string, codeset string) string { cdomainname := C.CString(domainname) ccodeset := C.CString(codeset) res := C.GoString(C.bind_textdomain_codeset(cdomainname, ccodeset)) C.free(unsafe.Pointer(cdomainname)) C.free(unsafe.Pointer(ccodeset)) return res } // Sets or retrieves the current message domain. func Textdomain(domainname string) string { cdomainname := C.CString(domainname) res := C.GoString(C.textdomain(cdomainname)) C.free(unsafe.Pointer(cdomainname)) return res } // Attempt to translate a text string into the user's native language, by // looking up the translation in a message catalog. func Gettext(msgid string) string { cmsgid := C.CString(msgid) res := C.GoString(C.gettext(cmsgid)) C.free(unsafe.Pointer(cmsgid)) return res } // Like Gettext(), but looking up the message in the specified domain. func DGettext(domain string, msgid string) string { cdomain := C.CString(domain) cmsgid := C.CString(msgid) res := C.GoString(C.dgettext(cdomain, cmsgid)) C.free(unsafe.Pointer(cdomain)) C.free(unsafe.Pointer(cmsgid)) return res } // Like Gettext(), but looking up the message in the specified domain and // category. func DCGettext(domain string, msgid string, category uint) string { cdomain := C.CString(domain) cmsgid := C.CString(msgid) res := C.GoString(C.dcgettext(cdomain, cmsgid, C.int(category))) C.free(unsafe.Pointer(cdomain)) C.free(unsafe.Pointer(cmsgid)) return res } // Attempt to translate a text string into the user's native language, by // looking up the appropriate plural form of the translation in a message // catalog. func NGettext(msgid string, msgid_plural string, n uint64) string { cmsgid := C.CString(msgid) cmsgid_plural := C.CString(msgid_plural) res := C.GoString(C.ngettext(cmsgid, cmsgid_plural, C.ulong(n))) C.free(unsafe.Pointer(cmsgid)) C.free(unsafe.Pointer(cmsgid_plural)) return res } // Like fmt.Sprintf() but without %!(EXTRA) errors. func Sprintf(format string, a ...interface{}) string { expects := strings.Count(format, "%") - strings.Count(format, "%%") if expects > 0 { arguments := make([]interface{}, expects) for i := 0; i < expects; i++ { if len(a) > i { arguments[i] = a[i] } } return fmt.Sprintf(format, arguments...) } return format } // Like NGettext(), but looking up the message in the specified domain. func DNGettext(domainname string, msgid string, msgid_plural string, n uint64) string { cdomainname := C.CString(domainname) cmsgid := C.CString(msgid) cmsgid_plural := C.CString(msgid_plural) res := C.GoString(C.dngettext(cdomainname, cmsgid, cmsgid_plural, C.ulong(n))) C.free(unsafe.Pointer(cdomainname)) C.free(unsafe.Pointer(cmsgid)) C.free(unsafe.Pointer(cmsgid_plural)) return res } // Like NGettext(), but looking up the message in the specified domain and // category. func DCNGettext(domainname string, msgid string, msgid_plural string, n uint64, category uint) string { cdomainname := C.CString(domainname) cmsgid := C.CString(msgid) cmsgid_plural := C.CString(msgid_plural) res := C.GoString(C.dcngettext(cdomainname, cmsgid, cmsgid_plural, C.ulong(n), C.int(category))) C.free(unsafe.Pointer(cdomainname)) C.free(unsafe.Pointer(cmsgid)) C.free(unsafe.Pointer(cmsgid_plural)) return res } account-polld-0.1+16.04.20160308.1/gettext/README.md0000644000015600001650000000355412667556700021611 0ustar pbuserpbgroup00000000000000# gosexy/gettext Go bindings for [GNU gettext][1], an internationalization and localization library for writing multilingual systems. ## Requeriments The GNU C library. If you're using GNU/Linux, FreeBSD or OSX you should already have it. ## Installation Use `go get` to download and install the binding: ```sh go get github.com/gosexy/gettext ``` ## Usage ```go package main import ( "github.com/gosexy/gettext" "fmt" "os" ) func main() { gettext.BindTextdomain("example", ".") gettext.Textdomain("example") os.Setenv("LANGUAGE", "es_MX.utf8") gettext.SetLocale(gettext.LC_ALL, "") fmt.Println(gettext.Gettext("Hello, world!")) } ``` You can use `os.Setenv` to set the `LANGUAGE` environment variable or set it on a terminal: ```sh export LANGUAGE="es_MX.utf8" ./gettext-program ``` Note that `xgettext` does not officially support Go syntax yet, however, you can generate a valid `.pot` file by forcing `xgettest` to use the C++ syntax: ```sh xgettext -d example -s gettext_test.go -o example.pot -L c++ -i \ --keyword=NGettext:1,2 --keyword=Gettext ``` This will generate a `example.pot` file. After translating the `.pot` file, you must generate `.po` and `.mo` files and remember to set the UTF-8 charset. ```sh msginit -l es_MX -o example.po -i example.pot msgfmt -c -v -o example.mo example.po ``` Finally, move the `.mo` file to an appropriate location. ```sh mv example.mo examples/es_MX.utf8/LC_MESSAGES/example.mo ``` ## Documentation You can read `gosexy/gettext` documentation from a terminal ```sh go doc github.com/gosexy/gettext ``` Or you can [browse it](http://godoc.org/github.com/gosexy/gettext) online. The original gettext documentation could be very useful as well: ```sh man 3 gettext ``` Here's another [good tutorial][2] on using gettext. [1]: http://www.gnu.org/software/gettext/ [2]: http://oriya.sarovar.org/docs/gettext_single.html account-polld-0.1+16.04.20160308.1/data/0000755000015600001650000000000012667557117017553 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/data/account-polld.desktop0000644000015600001650000000030312667556700023703 0ustar pbuserpbgroup00000000000000[Desktop Entry] Categories=Office; Exec= GenericName=account-polld Name=Notifications NoDisplay=true Terminal=false Type=Application Icon=indicator-messages X-Ubuntu-Gettext-Domain=account-polld account-polld-0.1+16.04.20160308.1/update_translations.sh0000755000015600001650000000134112667556700023260 0ustar pbuserpbgroup00000000000000#!/bin/sh sources=$(find . -name '*.go' | xargs) domain='account-polld' pot_file=po/$domain.pot desktop=data/$domain.desktop sed -e 's/^Name=/_Name=/' $desktop > $desktop.tr /usr/bin/intltool-extract --update --type=gettext/ini $desktop.tr $domain xgettext -o $pot_file \ --add-comments \ --from-code=UTF-8 \ --c++ --qt --add-comments=TRANSLATORS \ --keyword=Gettext --keyword=tr --keyword=tr:1,2 --keyword=N_ --keyword=_description \ --package-name=$domain \ --copyright-holder='Canonical Ltd.' \ $sources $desktop.tr.h echo Removing $desktop.tr.h rm $desktop.tr.h if [ "$1" = "--commit" ] && [ -n "$(bzr status $pot_file)" ]; then echo Commiting $pot_file bzr commit -m "Updated translation template" $pot_file fi account-polld-0.1+16.04.20160308.1/cmd/0000755000015600001650000000000012667557117017405 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/cmd/account-polld/0000755000015600001650000000000012667557117022151 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/cmd/account-polld/main.go0000644000015600001650000001522212667556700023423 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "encoding/json" "fmt" "strings" "sync" "log" "launchpad.net/account-polld/accounts" "launchpad.net/account-polld/gettext" "launchpad.net/account-polld/plugins" "launchpad.net/account-polld/plugins/gmail" "launchpad.net/account-polld/plugins/twitter" "launchpad.net/account-polld/pollbus" "launchpad.net/account-polld/qtcontact" "launchpad.net/go-dbus/v1" ) type PostWatch struct { appId plugins.ApplicationId batches []*plugins.PushMessageBatch } /* Use identifiers and API keys provided by the respective webapps which are the official end points for the notifications */ const ( SERVICETYPE_WEBAPPS = "webapps" SERVICENAME_GMAIL = "com.ubuntu.developer.webapps.webapp-gmail_webapp-gmail" SERVICENAME_TWITTER = "com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter" ) const ( POSTAL_SERVICE = "com.ubuntu.Postal" POSTAL_INTERFACE = "com.ubuntu.Postal" POSTAL_OBJECT_PATH_PART = "/com/ubuntu/Postal/" ) var mainLoopOnce sync.Once func init() { startMainLoop() } func startMainLoop() { mainLoopOnce.Do(func() { go qtcontact.MainLoopStart() }) } func main() { // TODO NewAccount called here is just for playing purposes. postWatch := make(chan *PostWatch) // Initialize i18n gettext.SetLocale(gettext.LC_ALL, "") gettext.Textdomain("account-polld") gettext.BindTextdomain("account-polld", "/usr/share/locale") bus, err := dbus.Connect(dbus.SessionBus) if err != nil { log.Fatal("Cannot connect to bus", err) } pollBus := pollbus.New(bus) go postOffice(bus, postWatch) go monitorAccounts(postWatch, pollBus) if err := pollBus.Init(); err != nil { log.Fatal("Issue while setting up the poll bus:", err) } done := make(chan bool) <-done } func monitorAccounts(postWatch chan *PostWatch, pollBus *pollbus.PollBus) { // Note: the accounts monitored are all linked to webapps right now watcher := accounts.NewWatcher(SERVICETYPE_WEBAPPS) mgr := make(map[uint]*AccountManager) var wg sync.WaitGroup L: for { select { case data := <-watcher.C: if account, ok := mgr[data.AccountId]; ok { if data.Enabled { log.Println("New account data for existing account with id", data.AccountId) account.penaltyCount = 0 account.updateAuthData(data) wg.Add(1) go func() { defer wg.Done() // Poll() needs to be called asynchronously as otherwise qtcontacs' GetAvatar() will // raise an error: "QSocketNotifier: Can only be used with threads started with QThread" account.Poll(false) }() // No wg.Wait() here as it would break GetAvatar() again. // Instead we have a wg.Wait() before the PollChan polling below. } else { account.Delete() delete(mgr, data.AccountId) } } else if data.Enabled { var plugin plugins.Plugin switch data.ServiceName { case SERVICENAME_GMAIL: log.Println("Creating account with id", data.AccountId, "for", data.ServiceName) plugin = gmail.New(data.AccountId) case SERVICENAME_TWITTER: // This is just stubbed until the plugin exists. log.Println("Creating account with id", data.AccountId, "for", data.ServiceName) plugin = twitter.New() default: log.Println("Unhandled account with id", data.AccountId, "for", data.ServiceName) continue L } mgr[data.AccountId] = NewAccountManager(watcher, postWatch, plugin) mgr[data.AccountId].updateAuthData(data) wg.Add(1) go func() { defer wg.Done() // Poll() needs to be called asynchronously as otherwise qtcontacs' GetAvatar() will // raise an error: "QSocketNotifier: Can only be used with threads started with QThread" mgr[data.AccountId].Poll(true) }() // No wg.Wait() here as it would break GetAvatar() again. // Instead we have a wg.Wait() before the PollChan polling below. } case <-pollBus.PollChan: wg.Wait() // Finish all running Poll() calls before potentially polling the same accounts again for _, v := range mgr { if v.authData.Error != plugins.ErrTokenExpired { // Do not poll if the new token hasn't been loaded yet wg.Add(1) go func(accountManager *AccountManager) { defer wg.Done() accountManager.Poll(false) }(v) } else { log.Println("Skipping account with id", v.authData.AccountId, "as it is refreshing its token") } } wg.Wait() pollBus.SignalDone() } } } func postOffice(bus *dbus.Connection, postWatch chan *PostWatch) { for post := range postWatch { obj := bus.Object(POSTAL_SERVICE, pushObjectPath(post.appId)) for _, batch := range post.batches { notifs := batch.Messages overflowing := len(notifs) > batch.Limit for _, n := range notifs { // We're overflowing, so no popups. // See LP: #1527171 if overflowing { n.Notification.Card.Popup = false } } if overflowing { n := batch.OverflowHandler(notifs) n.Notification.Card.Persist = false notifs = append(notifs, n) } for _, n := range notifs { var pushMessage string if out, err := json.Marshal(n); err == nil { pushMessage = string(out) } else { log.Printf("Cannot marshall %#v to json: %s", n, err) continue } if _, err := obj.Call(POSTAL_INTERFACE, "Post", post.appId, pushMessage); err != nil { log.Println("Cannot call the Post Office:", err) log.Println("Message missed posting:", pushMessage) } } } } } // pushObjectPath returns the object path of the ApplicationId // for Push Notifications with the Quoted Package Name in the form of // /com/ubuntu/PushNotifications/QUOTED_PKGNAME // // e.g.; if the APP_ID is com.ubuntu.music", the returned object path // would be "/com/ubuntu/PushNotifications/com_2eubuntu_2eubuntu_2emusic func pushObjectPath(id plugins.ApplicationId) dbus.ObjectPath { idParts := strings.Split(string(id), "_") if len(idParts) < 2 { panic(fmt.Sprintf("APP_ID '%s' is not valid", id)) } pkg := POSTAL_OBJECT_PATH_PART for _, c := range idParts[0] { switch c { case '+', '.', '-', ':', '~', '_': pkg += fmt.Sprintf("_%x", string(c)) default: pkg += string(c) } } return dbus.ObjectPath(pkg) } account-polld-0.1+16.04.20160308.1/cmd/account-polld/account_manager.go0000644000015600001650000001477112667556700025635 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "errors" "log" "time" "launchpad.net/account-polld/accounts" "launchpad.net/account-polld/plugins" "launchpad.net/ubuntu-push/click" "launchpad.net/ubuntu-push/click/cblacklist" ) type AccountManager struct { watcher *accounts.Watcher authData accounts.AuthData plugin plugins.Plugin interval time.Duration postWatch chan *PostWatch authChan chan accounts.AuthData doneChan chan error penaltyCount int authFailureCount int } var ( pollTimeout = time.Duration(30 * time.Second) bootstrapPollTimeout = time.Duration(4 * time.Minute) maxCounter = 4 authTriesUntilPenalty = 3 authFailurePenalty = 10 ) var ( authError = errors.New("Skipped account") clickNotInstalledError = errors.New("Click not installed") ) var isBlacklisted = cblacklist.IsBlacklisted func NewAccountManager(watcher *accounts.Watcher, postWatch chan *PostWatch, plugin plugins.Plugin) *AccountManager { return &AccountManager{ watcher: watcher, plugin: plugin, postWatch: postWatch, authChan: make(chan accounts.AuthData, 1), doneChan: make(chan error, 1), } } func (a *AccountManager) Delete() { close(a.authChan) close(a.doneChan) } // Poll() always needs to be called asynchronously as otherwise qtcontacs' GetAvatar() // will raise an error: "QSocketNotifier: Can only be used with threads started with QThread" func (a *AccountManager) Poll(bootstrap bool) { gotNewAuthData := false if !a.authData.Enabled { if a.authData, gotNewAuthData = <-a.authChan; !gotNewAuthData { log.Println("Account", a.authData.AccountId, "no longer enabled") return } } if id, ok := click.ParseAppId(string(a.plugin.ApplicationId())); (ok == nil) && isBlacklisted(id) { log.Printf("Account %d is blacklisted, not polling", a.authData.AccountId) return } if a.penaltyCount > 0 { log.Printf("Leaving poll for account %d as penalty count is %d", a.authData.AccountId, a.penaltyCount) a.penaltyCount-- return } else if !gotNewAuthData && a.authData.Error != nil { // Retry to poll the account with a previous auth failure as that results in reauthentication in case of token expiry and in ignoring temporary network issues log.Println("Retrying to poll account with previous auth failure and id", a.authData.AccountId, "(results in reauthentication in case of token expiry and in ignoring temporary network issues)") a.authData.Error = nil } timeout := pollTimeout if bootstrap { timeout = bootstrapPollTimeout } log.Printf("Starting poll for account %d", a.authData.AccountId) go a.poll() select { case <-time.After(timeout): log.Println("Poll for account", a.authData.AccountId, "has timed out out after", timeout) a.penaltyCount++ case err := <-a.doneChan: if err == nil { log.Println("Poll for account", a.authData.AccountId, "was successful") a.authFailureCount = 0 a.penaltyCount = 0 } else { if err != clickNotInstalledError && err != authError { // Do not log the error twice log.Println("Poll for account", a.authData.AccountId, "has failed:", err) } if err == authError || err == plugins.ErrTokenExpired { // Increase the authFailureCount counter, except for when we did a poll which // raised a token expiry error when we did not get any new auth data this time. if err != plugins.ErrTokenExpired || gotNewAuthData { log.Println("Increasing the auth failure counter for account", a.authData.AccountId) a.authFailureCount++ } else { log.Println("Not increasing the auth failure counter for account", a.authData.AccountId, "as we do not have new auth data") } if a.authFailureCount >= authTriesUntilPenalty { a.penaltyCount = authFailurePenalty a.authFailureCount = 0 log.Println(authTriesUntilPenalty, "auth failures in a row for account", a.authData.AccountId, "-> skipping it for the next", a.penaltyCount, "poll cycles") } else if err == plugins.ErrTokenExpired && !gotNewAuthData { // If the error indicates that the authentication token has expired, request reauthentication // and mark the data as disabled. // Do not refresh immediately when we just got new (faulty) auth data as immediately trying // again is probably not going to help. Instead, we wait for the next poll cycle. a.watcher.Refresh(a.authData.AccountId) a.authData.Enabled = false a.authData.Error = err } } else if a.penaltyCount < maxCounter { a.authFailureCount = 0 a.penaltyCount++ } } } log.Printf("Ending poll for account %d", a.authData.AccountId) } func (a *AccountManager) poll() { log.Println("Polling account", a.authData.AccountId) if !isClickInstalled(a.plugin.ApplicationId()) { log.Println( "Skipping account", a.authData.AccountId, "as target click", a.plugin.ApplicationId(), "is not installed") a.doneChan <- clickNotInstalledError return } if a.authData.Error != nil { log.Println("Account", a.authData.AccountId, "failed to authenticate:", a.authData.Error) a.doneChan <- authError return } if bs, err := a.plugin.Poll(&a.authData); err != nil { log.Print("Error while polling ", a.authData.AccountId, ": ", err) a.doneChan <- err } else { for _, b := range bs { log.Println("Account", a.authData.AccountId, "has", len(b.Messages), b.Tag, "updates to report") } a.postWatch <- &PostWatch{batches: bs, appId: a.plugin.ApplicationId()} a.doneChan <- nil } } func (a *AccountManager) updateAuthData(authData accounts.AuthData) { a.authChan <- authData } func isClickInstalled(appId plugins.ApplicationId) bool { user, err := click.User() if err != nil { log.Println("User instance for click cannot be created to determine if click application", appId, "was installed") return false } app, err := click.ParseAppId(string(appId)) if err != nil { log.Println("Could not parse APP_ID for", appId) return false } return user.Installed(app, false) } account-polld-0.1+16.04.20160308.1/cmd/account-watcher-test/0000755000015600001650000000000012667557117023451 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/cmd/account-watcher-test/main.go0000644000015600001650000000055712667556700024730 0ustar pbuserpbgroup00000000000000package main import ( "fmt" "os" "launchpad.net/account-polld/accounts" ) func main() { // Expects a list of service names as command line arguments for data := range accounts.NewWatcher(os.Args[1]).C { if data.Error != nil { fmt.Println("Failed to authenticate account", data.AccountId, ":", data.Error) } else { fmt.Printf("%#v\n", data) } } } account-polld-0.1+16.04.20160308.1/cmd/qtcontact-test/0000755000015600001650000000000012667557117022362 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/cmd/qtcontact-test/main.go0000644000015600001650000000163212667556700023634 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "fmt" "os" "launchpad.net/account-polld/qtcontact" ) func main() { qtcontact.MainLoopStart() if len(os.Args) != 2 { fmt.Println("usage:", os.Args[0], "[email address]") os.Exit(1) } path := qtcontact.GetAvatar(os.Args[1]) fmt.Println("Avatar found:", path) } account-polld-0.1+16.04.20160308.1/accounts/0000755000015600001650000000000012667557117020461 5ustar pbuserpbgroup00000000000000account-polld-0.1+16.04.20160308.1/accounts/account-watcher.h0000644000015600001650000000314012667556700023714 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef ACCOUNT_WATCHER_H #define ACCOUNT_WATCHER_H #include typedef struct _AccountWatcher AccountWatcher; typedef void (*AccountEnabledCallback)(AccountWatcher *watcher, unsigned int account_id, const char *service_name, GError *error, int enabled, const char *client_id, const char *client_secret, const char *access_token, const char *token_secret, void *user_data); AccountWatcher *account_watcher_new(const char *service_type, AccountEnabledCallback callback, void *user_data); void account_watcher_refresh(AccountWatcher *watcher, unsigned int account_id); #endif account-polld-0.1+16.04.20160308.1/accounts/account-watcher.c0000644000015600001650000002514512667556700023720 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include #include #include #include #include "account-watcher.h" /* #define DEBUG */ #ifdef DEBUG # define trace(...) fprintf(stderr, __VA_ARGS__) #else # define trace(...) #endif struct _AccountWatcher { AgManager *manager; /* A hash table of the enabled accounts we know of. * Keys are account ID integers, and AccountInfo structs as values. */ GHashTable *services; gulong enabled_event_signal_id; gulong account_deleted_signal_id; AccountEnabledCallback callback; void *user_data; }; typedef struct _AccountInfo AccountInfo; struct _AccountInfo { AccountWatcher *watcher; /* Manage signin session for account */ AgAccountService *account_service; SignonAuthSession *session; GVariant *auth_params; GVariant *session_data; gulong enabled_signal_id; AgAccountId account_id; gboolean enabled; /* the last known state of the account */ }; static void account_info_clear_login(AccountInfo *info) { if (info->session_data) { g_variant_unref(info->session_data); info->session_data = NULL; } if (info->auth_params) { g_variant_unref(info->auth_params); info->auth_params = NULL; } if (info->session) { signon_auth_session_cancel(info->session); g_object_unref(info->session); info->session = NULL; } } static void account_info_free(AccountInfo *info) { account_info_clear_login(info); if (info->enabled_signal_id != 0) { g_signal_handler_disconnect( info->account_service, info->enabled_signal_id); } info->enabled_signal_id = 0; if (info->account_service) { g_object_unref(info->account_service); info->account_service = NULL; } g_free(info); } static void account_info_notify(AccountInfo *info, GError *error) { AgService *service = ag_account_service_get_service(info->account_service); const char *service_name = ag_service_get_name(service); char *client_id = NULL; char *client_secret = NULL; char *access_token = NULL; char *token_secret = NULL; if (info->auth_params != NULL) { /* Look up OAuth 2 parameters, falling back to OAuth 1 names */ g_variant_lookup(info->auth_params, "ClientId", "&s", &client_id); g_variant_lookup(info->auth_params, "ClientSecret", "&s", &client_secret); if (client_id == NULL) { g_variant_lookup(info->auth_params, "ConsumerKey", "&s", &client_id); } if (client_secret == NULL) { g_variant_lookup(info->auth_params, "ConsumerSecret", "&s", &client_secret); } } if (info->session_data != NULL) { g_variant_lookup(info->session_data, "AccessToken", "&s", &access_token); g_variant_lookup(info->session_data, "TokenSecret", "&s", &token_secret); } info->watcher->callback(info->watcher, info->account_id, service_name, error, info->enabled, client_id, client_secret, access_token, token_secret, info->watcher->user_data); } static void account_info_login_cb(GObject *source, GAsyncResult *result, void *user_data) { SignonAuthSession *session = (SignonAuthSession *)source; AccountInfo *info = (AccountInfo *)user_data; trace("Authentication for account %u complete\n", info->account_id); GError *error = NULL; info->session_data = signon_auth_session_process_finish(session, result, &error); account_info_notify(info, error); if (error != NULL) { trace("Authentication failed: %s\n", error->message); g_error_free(error); } } static void account_info_login(AccountInfo *info) { account_info_clear_login(info); AgAuthData *auth_data = ag_account_service_get_auth_data(info->account_service); GError *error = NULL; trace("Starting authentication session for account %u\n", info->account_id); info->session = signon_auth_session_new( ag_auth_data_get_credentials_id(auth_data), ag_auth_data_get_method(auth_data), &error); if (error != NULL) { trace("Could not set up auth session: %s\n", error->message); account_info_notify(info, error); g_error_free(error); g_object_unref(auth_data); return; } /* Tell libsignon-glib not to open a trust session as we have no UI */ GVariantBuilder builder; g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); g_variant_builder_add(&builder, "{sv}", SIGNON_SESSION_DATA_UI_POLICY, g_variant_new_int32(SIGNON_POLICY_NO_USER_INTERACTION)); info->auth_params = g_variant_ref_sink( ag_auth_data_get_login_parameters( auth_data, g_variant_builder_end(&builder))); signon_auth_session_process_async( info->session, info->auth_params, ag_auth_data_get_mechanism(auth_data), NULL, /* cancellable */ account_info_login_cb, info); ag_auth_data_unref(auth_data); } static void account_info_enabled_cb( AgAccountService *account_service, gboolean enabled, AccountInfo *info) { trace("account_info_enabled_cb for %u, enabled=%d\n", info->account_id, enabled); if (info->enabled == enabled) { /* no change */ return; } info->enabled = enabled; if (enabled) { account_info_login(info); } else { account_info_clear_login(info); // Send notification that account has been disabled */ account_info_notify(info, NULL); } } static AccountInfo *account_info_new(AccountWatcher *watcher, AgAccountService *account_service) { AccountInfo *info = g_new0(AccountInfo, 1); info->watcher = watcher; info->account_service = g_object_ref(account_service); AgAccount *account = ag_account_service_get_account(account_service); g_object_get(account, "id", &info->account_id, NULL); info->enabled_signal_id = g_signal_connect( account_service, "enabled", G_CALLBACK(account_info_enabled_cb), info); // Set initial state account_info_enabled_cb(account_service, ag_account_service_get_enabled(account_service), info); return info; } static void account_watcher_enabled_event_cb( AgManager *manager, AgAccountId account_id, AccountWatcher *watcher) { trace("enabled-event for %u\n", account_id); if (g_hash_table_contains(watcher->services, GUINT_TO_POINTER(account_id))) { /* We are already tracking this account */ return; } AgAccount *account = ag_manager_get_account(manager, account_id); if (account == NULL) { /* There was a problem looking up the account */ return; } /* Since our AgManager is restricted to a particular service type, * pick the first service for the account. */ GList *services = ag_account_list_services(account); if (services != NULL) { AgService *service = services->data; AgAccountService *account_service = ag_account_service_new( account, service); AccountInfo *info = account_info_new(watcher, account_service); g_object_unref(account_service); g_hash_table_insert(watcher->services, GUINT_TO_POINTER(account_id), info); } ag_service_list_free(services); g_object_unref(account); } static void account_watcher_account_deleted_cb( AgManager *manager, AgAccountId account_id, AccountWatcher *watcher) { trace("account-deleted for %u\n", account_id); /* A disabled event should have been sent prior to this, so no * need to send any notification. */ g_hash_table_remove(watcher->services, GUINT_TO_POINTER(account_id)); } static gboolean account_watcher_setup(void *user_data) { AccountWatcher *watcher = (AccountWatcher *)user_data; /* Track changes to accounts */ watcher->enabled_event_signal_id = g_signal_connect( watcher->manager, "enabled-event", G_CALLBACK(account_watcher_enabled_event_cb), watcher); watcher->account_deleted_signal_id = g_signal_connect( watcher->manager, "account-deleted", G_CALLBACK(account_watcher_account_deleted_cb), watcher); /* Now check initial state */ GList *enabled_accounts = ag_manager_list(watcher->manager); GList *l; for (l = enabled_accounts; l != NULL; l = l->next) { AgAccountId account_id = GPOINTER_TO_UINT(l->data); account_watcher_enabled_event_cb(watcher->manager, account_id, watcher); } ag_manager_list_free(enabled_accounts); return G_SOURCE_REMOVE; } AccountWatcher *account_watcher_new(const char *service_type, AccountEnabledCallback callback, void *user_data) { AccountWatcher *watcher = g_new0(AccountWatcher, 1); watcher->manager = ag_manager_new_for_service_type(service_type); watcher->services = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)account_info_free); watcher->callback = callback; watcher->user_data = user_data; /* Make sure main setup occurs within the mainloop thread */ g_idle_add(account_watcher_setup, watcher); return watcher; } struct refresh_info { AccountWatcher *watcher; AgAccountId account_id; }; static gboolean account_watcher_refresh_cb(void *user_data) { struct refresh_info *data = (struct refresh_info *)user_data; AccountInfo *info = g_hash_table_lookup( data->watcher->services, GUINT_TO_POINTER(data->account_id)); if (info != NULL) { account_info_login(info); } return G_SOURCE_REMOVE; } void account_watcher_refresh(AccountWatcher *watcher, unsigned int account_id) { struct refresh_info *data = g_new(struct refresh_info, 1); data->watcher = watcher; data->account_id = account_id; g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, account_watcher_refresh_cb, data, g_free); } account-polld-0.1+16.04.20160308.1/accounts/accounts.c0000644000015600001650000000166412667556700022450 0ustar pbuserpbgroup00000000000000#include "_cgo_export.h" AccountWatcher *watch_for_service_type(const char *service_type) { /* Transfer service names to hash table */ if (FALSE) { /* The Go callback doesn't quite match the * AccountEnabledCallback function prototype, so we cast the * argument in the account_watcher_new() call below. * * This is just a check to see that the function still has the * prototype we expect. */ void (*unused)(void *watcher, unsigned int account_id, char *service_name, GError *error, int enabled, char *client_id, char *client_secret, char *access_token, char *token_secret, void *user_data) = authCallback; } AccountWatcher *watcher = account_watcher_new( service_type, (AccountEnabledCallback)authCallback, NULL); return watcher; } account-polld-0.1+16.04.20160308.1/accounts/accounts.go0000644000015600001650000000553112667556700022630 0ustar pbuserpbgroup00000000000000/* Copyright 2014 Canonical Ltd. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License version 3, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranties of MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package accounts /* #cgo pkg-config: glib-2.0 libaccounts-glib libsignon-glib #include #include #include "account-watcher.h" AccountWatcher *watch_for_service_type(const char *service_type); */ import "C" import ( "errors" "sync" "unsafe" ) type Watcher struct { C <-chan AuthData watcher *C.AccountWatcher } type AuthData struct { AccountId uint ServiceName string Error error Enabled bool ClientId string ClientSecret string AccessToken string TokenSecret string } var ( authChannels = make(map[*C.AccountWatcher]chan<- AuthData) authChannelsLock sync.Mutex ) // NewWatcher creates a new account watcher for the given service names func NewWatcher(serviceType string) *Watcher { w := new(Watcher) cServiceType := C.CString(serviceType) defer C.free(unsafe.Pointer(cServiceType)) w.watcher = C.watch_for_service_type(cServiceType) ch := make(chan AuthData) w.C = ch authChannelsLock.Lock() authChannels[w.watcher] = ch authChannelsLock.Unlock() return w } // Refresh requests that the token for the given account be refreshed. // The new access token will be delivered over the watcher's channel. func (w *Watcher) Refresh(accountId uint) { C.account_watcher_refresh(w.watcher, C.uint(accountId)) } //export authCallback func authCallback(watcher unsafe.Pointer, accountId C.uint, serviceName *C.char, error *C.GError, enabled C.int, clientId, clientSecret, accessToken, tokenSecret *C.char, userData unsafe.Pointer) { // Ideally the first argument would be of type // *C.AccountWatcher, but that fails with Go 1.2. authChannelsLock.Lock() ch := authChannels[(*C.AccountWatcher)(watcher)] authChannelsLock.Unlock() if ch == nil { // Log the error return } var data AuthData data.AccountId = uint(accountId) data.ServiceName = C.GoString(serviceName) if error != nil { data.Error = errors.New(C.GoString((*C.char)(error.message))) } if enabled != 0 { data.Enabled = true } if clientId != nil { data.ClientId = C.GoString(clientId) } if clientSecret != nil { data.ClientSecret = C.GoString(clientSecret) } if accessToken != nil { data.AccessToken = C.GoString(accessToken) } if tokenSecret != nil { data.TokenSecret = C.GoString(tokenSecret) } ch <- data }